我正在使用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
标记处于打开状态,数据总是会改变。
请为我解释原因。 谢谢
答案 0 :(得分:1)
case (acc,x) => acc + (x->(acc(x)+1)) + ("total"->(acc("total")+1))
是事务的显式开始,它禁用了BEGIN
的效果。
自动提交适用于未明确进行事务处理的SQL。
答案 1 :(得分:1)
即使打开autocommit
,如果您使用BEGIN
或START TRANSACTION
,它也会暂时挂起每个语句的自动提交,直到完成事务为止。
您引用了手册页https://dev.mysql.com/doc/refman/8.0/en/commit.html,该页继续说明:
要隐式禁用单个语句系列的自动提交模式,请使用START TRANSACTION语句:
使用START TRANSACTION,自动提交将保持禁用,直到您使用COMMIT或ROLLBACK结束事务。然后,自动提交模式将恢复为之前的状态。
(重点是我的)
换句话说,在BEGIN
或START TRANSACTION
之后执行的语句是 not 自动提交的。这是预期的。
答案 2 :(得分:1)
虽然前面的答案是正确的,但让我指出另一个角度。
如果运行十亿行UPDATE
(这将花费数小时),然后拔下计算机上的插头,则UPDATE
将部分完成。重新启动计算机(和MySQL)后,会发生什么?在MyISAM中,某些行将被更新,而某些行将不被更新。但是使用InnoDB,它将ROLLBACK
部分完成的UPDATE
(并且可能需要更多时间才能完成)。
因此,手册中的引用不仅含糊不清(如其他答案所指出的那样),而且在字面上也是错误的。在我的示例中,更改可以和被回滚。
我喜欢这样表达:
Autocommit=ON
在没有事务的情况下等效于将语句包装在BEGIN
和COMMIT
中。也就是说,该语句是原子执行的。