Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL:自动提交标志已启用,但事务仍可以回滚_Mysql_Mariadb_Autocommit - Fatal编程技术网

MySQL:自动提交标志已启用,但事务仍可以回滚

MySQL:自动提交标志已启用,但事务仍可以回滚,mysql,mariadb,autocommit,Mysql,Mariadb,Autocommit,我使用的是MariaDB版本10.3.13。上次我检查时,autocommit标志处于启用状态 MariaDB> SHOW VARIABLES WHERE Variable_name='autocommit'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | autocommit | ON | +---------------+-------+ 正如我在文档中读到的

我使用的是MariaDB版本
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
一样运行。