MySQL:自动提交标志处于启用状态,但事务仍然可以回滚

时间:2019-05-01 21:29:02

标签: mysql mariadb autocommit

我正在使用MariaDB版本10.3.13。我上次检查时,autocommit标志处于启用状态。

MariaDB> SHOW VARIABLES WHERE Variable_name='autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+

当我阅读文档时,启用自动提交功能后,您将无法按照here所述回退事务

  

默认情况下,MySQL在启用自动提交模式的情况下运行。这意味着   一旦执行更新(修改)表的语句,   MySQL将更新存储在磁盘上以使其永久存在。改变   无法回滚。

所以我写了一个小脚本进行测试。首先,我开始交易并更新一些数据:

BEGIN;
UPDATE foo SET year = 2019  WHERE id = 1;
Query OK, 1 row affected (0.000 sec)
Rows matched: 1  Changed: 1  Warnings: 0

所以看来我已经完成了。然后我回滚:

ROLLBACK;
Query OK, 0 rows affected (0.005 sec)

然后我再次检查更新的记录,发现数据没有更改。这很奇怪,因为我认为无论autocommit标记处于打开状态,数据总是会改变。

请为我解释原因。 谢谢

3 个答案:

答案 0 :(得分:1)

case (acc,x) => acc + (x->(acc(x)+1)) + ("total"->(acc("total")+1))是事务的显式开始,它禁用了BEGIN的效果。

自动提交适用于未明确进行事务处理的SQL。

答案 1 :(得分:1)

即使打开autocommit,如果您使用BEGINSTART TRANSACTION,它也会暂时挂起每个语句的自动提交,直到完成事务为止。

您引用了手册页https://dev.mysql.com/doc/refman/8.0/en/commit.html,该页继续说明:

  

要隐式禁用单个语句系列的自动提交模式,请使用START TRANSACTION语句:

     

使用START TRANSACTION,自动提交将保持禁用,直到您使用COMMIT或ROLLBACK结束事务。然后,自动提交模式将恢复为之前的状态。

(重点是我的)

换句话说,在BEGINSTART TRANSACTION之后执行的语句是 not 自动提交的。这是预期的。

答案 2 :(得分:1)

虽然前面的答案是正确的,但让我指出另一个角度。

如果运行十亿行UPDATE(这将花费数小时),然后拔下计算机上的插头,则UPDATE将部分完成。重新启动计算机(和MySQL)后,会发生什么?在MyISAM中,某些行将被更新,而某些行将不被更新。但是使用InnoDB,它将ROLLBACK部分完成的UPDATE(并且可能需要更多时间才能完成)。

因此,手册中的引用不仅含糊不清(如其他答案所指出的那样),而且在字面上也是错误的。在我的示例中,更改可以回滚。

我喜欢这样表达:

  

Autocommit=ON在没有事务的情况下等效于将语句包装在BEGINCOMMIT中。也就是说,该语句是原子执行的。

我提交了http://bugs.mysql.com/95414