Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  START TRANSACTION, COMMIT, and ROLLBACK Statements

15.3.1 开始事务、提交和回滚语句

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 take no effect。忽略时生成警告。

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

    MySQL 对 InnoDB 表进行额外优化,当事务已知为只读时。指定READ ONLY 确保这些优化在无法自动确定只读状态的情况下被应用。更多信息请参见第10.5.3节,“Optimizing InnoDB Read-Only Transactions”

    如果未指定访问模式,应用默认模式。除非默认模式已被更改,它是读写模式。不能在同一语句中同时指定READ WRITEREAD ONLY

    只读模式下,可以使用 DML 语句修改以TEMPORARY 关键字创建的表。DDL 语句不能修改,和永久表一样。

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

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

Important

许多用于编写 MySQL 客户端应用程序的 API(例如 JDBC)提供了自己的方法来启动事务,可以(有时应该)而不是从客户端发送 START TRANSACTION 语句。见第31章,连接器和 API,或者您的 API 文档,以获取更多信息。

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

SET autocommit=0;

在设置autocommit 变量为零后,事务安全表(例如InnoDBNDB 的更改不会立即持久化。你必须使用COMMIT 将更改存储到磁盘或 ROLLBACK 忽略更改。

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

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

BEGIN 语句不同于开始BEGIN ... END复合语句的用法 Latter 不会启动事务。见第15.6.1节,“BEGIN ... END复合语句”

Note

在所有存储程序(存储过程、函数、触发器和事件)中,解析器将 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)的表,并且事务隔离级别不是SERIALIZABLESET 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 语句执行的隐式回滚,也包括隐式回滚。

Note

在 MySQL 8.4 中,BEGINCOMMITROLLBACK 不受--replicate-do-db--replicate-ignore-db 规则影响。

InnoDB 完全回滚事务时,事务设置的所有锁都被释放。如果事务中的单个 SQL 语句由于错误(例如重复键错误)而回滚,语句设置的锁将保留直到事务保持活动状态。这是因为 InnoDB 将行锁存储在格式中无法知道后来哪个锁由哪个语句设置。

如果事务中的SELECT语句调用存储函数,并且存储函数中的语句失败,那么该语句回滚。如果后续执行ROLLBACK,整个事务也会回滚。