文档首页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (美国字母) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  START TRANSACTION、COMMIT 和 ROLLBACK 语句

15.3.1 START TRANSACTION、COMMIT 和 ROLLBACK 语句

START TRANSACTION
    [transaction_characteristic [, transaction_characteristic] ...]

transaction_characteristic: {
    WITH CONSISTENT SNAPSHOT
  | READ WRITE
  | READ ONLY
}

BEGIN [WORK]
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
SET autocommit = {0 | 1}

这些语句提供对使用 事务 的控制

  • START TRANSACTIONBEGIN 启动一个新事务。

  • COMMIT 提交当前事务,使其更改永久生效。

  • ROLLBACK 回滚当前事务,取消其更改。

  • SET autocommit 禁用或启用当前会话的默认自动提交模式。

默认情况下,MySQL 以 自动提交 模式运行。这意味着,如果没有在其他事务中,每个语句都是原子的,就像它被 START TRANSACTIONCOMMIT 包围一样。您不能使用 ROLLBACK 来撤消其效果;但是,如果在语句执行期间发生错误,该语句将回滚。

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

START TRANSACTION;
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summary=@A WHERE type=1;
COMMIT;

使用 START TRANSACTION,自动提交将保持禁用状态,直到您使用 COMMITROLLBACK 结束事务。然后自动提交模式将恢复到其先前状态。

START TRANSACTION 允许使用几个修饰符来控制事务特性。要指定多个修饰符,请用逗号隔开它们。

  • 使用 WITH CONSISTENT SNAPSHOT 修饰符开始对支持一致性读取的存储引擎执行一致性读取。这仅适用于 InnoDB。其效果与先执行 START TRANSACTION,然后从任何 InnoDB 表执行 SELECT 相同。参见 第 17.7.2.3 节,“一致性非锁定读取”WITH CONSISTENT SNAPSHOT 修饰符不会更改当前事务的 隔离级别,因此只有在当前隔离级别允许一致性读取的情况下,它才能提供一致性快照。唯一允许一致性读取的隔离级别是 REPEATABLE READ。对于所有其他隔离级别,WITH CONSISTENT SNAPSHOT 子句将被忽略。如果忽略了 WITH CONSISTENT SNAPSHOT 子句,则会生成警告。

  • 使用 READ WRITEREAD ONLY 修饰符设置事务访问模式。它们允许或禁止更改事务中使用的表。READ ONLY 限制阻止事务修改或锁定对其他事务可见的事务表和非事务表;但事务仍可以修改或锁定临时表。

    当事务被识别为只读时,MySQL 会针对 InnoDB 表上的查询启用额外的优化。指定 READ ONLY 确保在无法自动确定只读状态的情况下应用这些优化。有关更多信息,请参见 第 10.5.3 节,“优化 InnoDB 只读事务”

    如果未指定访问模式,则将应用默认模式。除非已更改默认值,否则为读写模式。不允许在同一语句中同时指定 READ WRITEREAD ONLY

    在只读模式下,仍可以使用 DML 语句更改使用 TEMPORARY 关键字创建的表。与永久表一样,不允许使用 DDL 语句进行更改。

    有关事务访问模式的更多信息,包括更改默认模式的方法,请参见 第 15.3.7 节,“SET TRANSACTION 语句”

    如果启用了 read_only 系统变量,则显式使用 START TRANSACTION READ WRITE 启动事务需要 CONNECTION_ADMIN 权限(或已弃用的 SUPER 权限)。

重要

用于编写 MySQL 客户端应用程序的许多 API(如 JDBC)提供它们自己的启动事务的方法,这些方法可以(有时应该)代替从客户端发送 START TRANSACTION 语句。有关更多信息,请参见 第 31 章,连接器和 API 或 API 文档。

要显式禁用自动提交模式,请使用以下语句

SET autocommit=0;

在通过将 autocommit 变量设置为零禁用自动提交模式后,对事务安全表(如 InnoDBNDB 的表)的更改不会立即永久保存。您必须使用 COMMIT 将更改存储到磁盘或使用 ROLLBACK 忽略这些更改。

autocommit 是一个会话变量,必须为每个会话设置。要为每个新连接禁用自动提交模式,请参见 autocommit 系统变量的描述,位于 第 7.1.8 节,“服务器系统变量”

BEGINBEGIN WORK 支持作为 START TRANSACTION 的别名来启动事务。 START TRANSACTION 是标准 SQL 语法,是启动临时事务的推荐方法,并允许 BEGIN 不允许的修饰符。

BEGIN 语句不同于用于启动 BEGIN ... END 复合语句的 BEGIN 关键字的用法。后者不会启动事务。参见 第 15.6.1 节,“BEGIN ... END 复合语句”

注意

在所有存储程序(存储过程和函数、触发器和事件)中,解析器将 BEGIN [WORK] 视为 BEGIN ... END 块的开头。在此上下文中,请使用 START TRANSACTION 启动事务。

可选的 WORK 关键字支持 COMMITROLLBACK,以及 CHAINRELEASE 子句。 CHAINRELEASE 可用于对事务完成进行更多控制。 completion_type 系统变量的值决定默认的完成行为。参见 第 7.1.8 节,“服务器系统变量”

使用 AND CHAIN 子句会导致在当前事务结束时立即开始新事务,并且新事务具有与刚刚结束的事务相同的隔离级别。新事务还使用与刚刚结束的事务相同的访问模式(READ WRITEREAD ONLY)。RELEASE 子句会导致服务器在终止当前事务后断开当前客户端会话的连接。包括 NO 关键字将抑制 CHAINRELEASE 完成,如果 completion_type 系统变量设置为默认情况下导致链接或释放完成,这将很有用。

启动事务会导致提交任何挂起的事务。有关更多信息,请参见 第 15.3.3 节,“导致隐式提交的语句”

启动事务还会导致使用 LOCK TABLES 获取的表锁被释放,就好像您已经执行了 UNLOCK TABLES 一样。启动事务不会释放使用 FLUSH TABLES WITH READ LOCK 获取的全局读取锁。

为了获得最佳效果,应仅使用由单个事务安全存储引擎管理的表执行事务。否则,可能会出现以下问题

  • 如果使用来自多个事务安全存储引擎(如 InnoDB)的表,并且事务隔离级别不是 SERIALIZABLE,那么当一个事务提交时,另一个使用相同表的正在进行的事务可能只看到第一个事务进行的某些更改。也就是说,在混合引擎的情况下,无法保证事务的原子性,并且会导致不一致。(如果混合引擎事务很少见,则可以使用 SET TRANSACTION ISOLATION LEVEL 在必要时按事务将隔离级别设置为 SERIALIZABLE。)

  • 如果在事务中使用非事务安全的表,则对这些表的更改会立即存储,而与自动提交模式的状态无关。

  • 如果在事务中更新非事务表后发出 ROLLBACK 语句,则会发生 ER_WARNING_NOT_COMPLETE_ROLLBACK 警告。对事务安全表的更改将回滚,但对非事务安全表的更改不会回滚。

每个事务在 COMMIT 时以一个块的形式存储在二进制日志中。回滚的事务不会被记录。(例外:对非事务表的修改无法回滚。如果回滚的事务包含对非事务表的修改,则整个事务将记录在结尾处使用 ROLLBACK 语句,以确保对非事务表的修改被复制。)参见 第 7.4.4 节,“二进制日志”

您可以使用 SET TRANSACTION 语句更改事务的隔离级别或访问模式。参见 第 15.3.7 节,“SET TRANSACTION 语句”

回滚可能是一个缓慢的操作,它可能会隐式发生,而用户没有明确要求(例如,当发生错误时)。因此,SHOW PROCESSLISTState 列中显示 Rolling back,不仅针对使用 ROLLBACK 语句执行的显式回滚,还针对隐式回滚。

注意

在 MySQL 9.0 中,BEGINCOMMITROLLBACK 不会受到 --replicate-do-db--replicate-ignore-db 规则的影响。

InnoDB 完全回滚事务时,事务设置的所有锁都会被释放。如果事务中的单个 SQL 语句由于错误(如重复键错误)而回滚,则该语句设置的锁将保留,而事务仍处于活动状态。发生这种情况是因为 InnoDB 以一种格式存储行锁,因此无法事后知道哪个锁是由哪个语句设置的。

如果事务中的 SELECT 语句调用存储函数,并且存储函数中的语句失败,则该语句将回滚。如果随后对事务执行 ROLLBACK,则整个事务将回滚。