假设mariadb兼容的数据库(aws aurora rds)具有默认设置,其中包括启用自动提交,如果lambda函数在执行一个需要5秒以上的事务的3秒后终止,例如。
tx, err := h.db.Begin()
if err != nil {
log.WithError(err).Error("failed to start transaction")
}
res, execErr := tx.Exec(fmt.Sprintf("UPDATE testtable SET val = %d WHERE id = 1; SELECT SLEEP(5.5);", time.Now().Unix()))
if execErr != nil {
log.WithError(err).Error("rolling back")
err = tx.Rollback()
if err != nil {
log.WithError(err).Error("failed to roll back")
}
}
if err := tx.Commit(); err != nil {
log.WithError(err).Error("failed to commit")
}
我们会假设结果是什么?交易不会被提交?
我正在使用go-mysql驱动程序v1.3.0-84-g6be42e0 btw。我还制作了一个视频来显示我的结果,但我不知道它是否正确,因为我不明白驱动程序是如何执行回滚的。
2条答案
按热度按时间klh5stk11#
如果您使用innodb表,请从https://dev.mysql.com/doc/internals/en/transactions-life-cycle.html:
当连接关闭时,将回滚当前的正常事务(如果有)。
这与go客户机、java客户机、php客户机或任何其他客户机的工作原理相同。
如果使用myisam表,就没有回滚。如果当前正在执行sql更新,它可能会更新某些行的子集,而保留其余行不变。您将得到一个状态不一致的表。非事务表没有acid行为。这就是为什么你不应该使用myisam。
kkbh8khc2#
事务sql不提交。我相信在<=5s超时时会发生什么:
开始交易
同步执行sql
mysqld检测到客户端通过tcp-fin断开连接
mysqld自动回滚,因为它看不到提交
一位golang mysql驱动程序维护人员的tweet回复:
mysqld在go客户端终止时接收tcp-fin包。
即使go客户端不干净地退出,os(linux内核等)也会发送tcp-fin或tcp-rst。这样mysqld就可以知道客户不在了。
-稻田直树(@甲烷)2018年12月4日