MySQL:自动提交标志已启用,但事务仍可以回滚
我使用的是MariaDB版本MySQL:自动提交标志已启用,但事务仍可以回滚,mysql,mariadb,autocommit,Mysql,Mariadb,Autocommit,我使用的是MariaDB版本10.3.13。上次我检查时,autocommit标志处于启用状态 MariaDB> SHOW VARIABLES WHERE Variable_name='autocommit'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | autocommit | ON | +---------------+-------+ 正如我在文档中读到的
10.3.13
。上次我检查时,autocommit
标志处于启用状态
MariaDB> SHOW VARIABLES WHERE Variable_name='autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
正如我在文档中读到的,当“自动提交”处于启用状态时,您不能按所述回滚事务
默认情况下,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
标志处于启用状态
MariaDB> SHOW VARIABLES WHERE Variable_name='autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
请给我解释一下原因。
谢谢
开始
是一个明确的事务开始,它禁用了自动提交
的效果
自动提交适用于非显式事务性的SQL。即使启用了
自动提交
,如果使用开始
或开始事务
,它也会临时挂起每条语句的自动提交,直到您完成事务
您引用了手册页面,该页面接着解释:
要对一系列语句隐式禁用自动提交模式,请使用START TRANSACTION语句:
使用“启动事务”时,自动提交将保持禁用状态,直到您使用提交或回滚结束事务。自动提交模式随后恢复到以前的状态
(强调矿山)
换句话说,在
BEGIN
或START TRANSACTION
之后执行的语句不会自动提交。这是意料之中的。虽然前面的答案是正确的,但让我指出另一个角度
如果运行十亿行更新
(需要几个小时),并拔下计算机上的插头,则更新
将部分完成。重新启动计算机(和MySQL)时,会发生什么?在MyISAM中,有些行会被更新,有些行不会。但是使用InnoDB,它将回滚部分完成的更新
(这样做可能需要更多的时间)
因此,手册中的引用不仅含糊不清(正如其他答案所指出的),而且“字面上”是不正确的。在我的示例中,更改可以并已回滚
我想这样说:
Autocommit=ON
,当事务中没有其他内容时,相当于将语句包装在BEGIN
和COMMIT
中。也就是说,该语句是以原子方式执行的
我提交了。如果您运行十亿行更新:那么您的意思是我们将在事务块内运行此查询?谢谢。@TrầnKimDự - 从逻辑上讲,是的。它将像在其周围添加了BEGIN
和COMMIT
一样运行。