【问题标题】:MySQL: autocommit flag is on but transaction still can rollbackMySQL:自动提交标志打开,但事务仍然可以回滚
【发布时间】:2019-09-20 09:56:37
【问题描述】:

我正在使用 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 标志是打开的。

请解释一下原因。 谢谢

【问题讨论】:

    标签: mysql mariadb autocommit


    【解决方案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 之后执行的语句不会自动提交。这是意料之中的。

    【讨论】:

      【解决方案2】:

      BEGIN 是一个显式的事务开始,它禁用了autocommit 的效果。

      自动提交适用于非明确事务性的 SQL。

      【讨论】:

        【解决方案3】:

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

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

        因此,手册中的引用不仅模棱两可(正如其他答案所指出的那样),而且“字面上”不正确。在我的示例中,更改可以并且已回滚。

        我喜欢这样说:

        Autocommit=ON,当不在事务中时,相当于将语句包装在BEGIN 和COMMIT 中。也就是说,语句是原子执行的。

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

        【讨论】:

        • 如果您运行十亿行 UPDATE: 那么您的意思是我们将在事务块内运行此查询?谢谢。
        • @TrầnKimDự - 从逻辑上讲,是的。它将像您在其周围添加 BEGIN 和 COMMIT 一样运行。
        猜你喜欢
        • 2012-12-24
        • 2013-11-22
        • 1970-01-01
        • 2013-05-16
        • 2019-04-23
        • 2015-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多