8.4 中文镜像

MySQL 8.4 参考手册 · 中文镜像

正文为中文,英文原文默认隐藏。点击任意中文段落即可展开 / 收起对应英文原文。

打开官方英文原文 ↗

译文由机器翻译生成,仅供理解参考;有疑问请以官方英文原文为准。

MySQL 8.4 参考手册 / 15 条 SQL 语句 / 15.3 事务和锁定语句 / 15.3.1 开始事务、提交和回滚语句
中文点击中文段落可显示 / 隐藏英文原文本页译文覆盖 100%

15.3.1 START TRANSACTION、COMMIT 和 ROLLBACK 语句15.3.1 START TRANSACTION, COMMIT, and ROLLBACK Statements

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}

这些语句提供了对事务使用的控制:These statements provide control over use of transactions:

  • START TRANSACTION 或 BEGIN 开始一个新事务。START TRANSACTION or BEGIN start a new transaction.

  • COMMIT 提交当前事务,使其更改永久生效。COMMIT commits the current transaction, making its changes permanent.

  • ROLLBACK 回滚当前事务,取消其更改。ROLLBACK rolls back the current transaction, canceling its changes.

  • SET autocommit 禁用或启用当前会话的默认自动提交模式。SET autocommit disables or enables the default autocommit mode for the current session.

默认情况下,MySQL 在启用 自动提交 模式下运行。这意味着,当不处于事务中时,每个语句都是原子性的,就像它们被 START TRANSACTION 和 COMMIT 包围一样。您不能使用 ROLLBACK 来撤销效果;但是,如果在语句执行过程中发生错误,该语句将回滚。By default, MySQL runs with autocommit mode enabled. This means that, when not otherwise inside a transaction, each statement is atomic, as if it were surrounded by START TRANSACTION and COMMIT. You cannot use ROLLBACK to undo the effect; however, if an error occurs during statement execution, the statement is rolled back.

要在单次语句序列中隐式禁用自动提交模式,请使用 START TRANSACTION 语句:To disable autocommit mode implicitly for a single series of statements, use the START TRANSACTION statement:

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

使用 START TRANSACTION 时,自动提交保持禁用,直到您通过 COMMIT 或 ROLLBACK 结束事务。然后自动提交模式恢复到先前状态。With START TRANSACTION, autocommit remains disabled until you end the transaction with COMMIT or ROLLBACK. The autocommit mode then reverts to its previous state.

START TRANSACTION 允许使用多个修饰符来控制事务特性。要指定多个修饰符,请用逗号分隔它们。START TRANSACTION permits several modifiers that control transaction characteristics. To specify multiple modifiers, separate them by commas.

  • WITH CONSISTENT SNAPSHOT饰符启动 一致读取,适用于具备此功能的存储引擎。这仅适用于 InnoDB。其效果类似于发出 START TRANSACTION 后接 SELECT 从任意 InnoDB。参见 第 17.7.2.3 节,“Consistent Nonlocking Reread”。WITH CONSISTENT SNAPSHOT饰符不会改变当前事务隔离级别,因此只有当前隔离级别允许一致读取时才提供一致快照。唯一允许一致读取的隔离级别是 REPEATABLE READ对于所有其他隔离层,WITH CONSISTENT SNAPSHOT句被忽略。当忽略 WITH CONSISTENT SNAPSHOT。The WITH CONSISTENT SNAPSHOT modifier starts a consistent read for storage engines that are capable of it. This applies only to InnoDB. The effect is the same as issuing a START TRANSACTION followed by a SELECT from any InnoDB table. See Section 17.7.2.3, “Consistent Nonlocking Reads”. The WITH CONSISTENT SNAPSHOT modifier does not change the current transaction isolation level, so it provides a consistent snapshot only if the current isolation level is one that permits a consistent read. The only isolation level that permits a consistent read is REPEATABLE READ. For all other isolation levels, the WITH CONSISTENT SNAPSHOT clause is ignored. A warning is generated when the WITH CONSISTENT SNAPSHOT clause is ignored.

  • READ WRITE 和 READ ONLY 修饰符设置事务访问模式。它们允许或禁止对事务中使用的表进行更改。READ ONLY 限制防止事务修改或锁定对其他事务可见的事务表和非事务表;事务仍可修改或锁定临时表。The READ WRITE and READ ONLY modifiers set the transaction access mode. They permit or prohibit changes to tables used in the transaction. The READ ONLY restriction prevents the transaction from modifying or locking both transactional and nontransactional tables that are visible to other transactions; the transaction can still modify or lock temporary tables.

    MySQL 在事务已知为只读时,允许对 InnoDB。指定 READ ONLY 确保在无法自动确定只读状态的情况下应用这些优化。更多信息请参见 第 10.5.3 节,“优化 InnoDB 只读事务”。MySQL enables extra optimizations for queries on InnoDB tables when the transaction is known to be read-only. Specifying READ ONLY ensures these optimizations are applied in cases where the read-only status cannot be determined automatically. See Section 10.5.3, “Optimizing InnoDB Read-Only Transactions” for more information.

    如果未指定访问模式,则采用默认模式。除非默认模式被更改,否则为读写。同一语句中不得同时指定 READ WRITE 和 READ ONLY。If no access mode is specified, the default mode applies. Unless the default has been changed, it is read/write. It is not permitted to specify both READ WRITE and READ ONLY in the same statement.

    在只读模式下,仍可使用 DML 语句更改使用TEMPORARY。不允许对 DDL 语句进行更改,与永久表相同。In read-only mode, it remains possible to change tables created with the TEMPORARY keyword using DML statements. Changes made with DDL statements are not permitted, just as with permanent tables.

    有关事务访问模式的更多信息,包括更改默认模式的方法,请参见 第 15.3.7 节,“SET TRANSACTION Statement”。For additional information about transaction access mode, including ways to change the default mode, see Section 15.3.7, “SET TRANSACTION Statement”.

    如果启用了 read_only系统变量,显式启动事务时,显式地以 START TRANSACTION READ WRITE 启动事务需要 CONNECTION_ADMIN权限(或已废弃的 SUPER 权限)。If the read_only system variable is enabled, explicitly starting a transaction with START TRANSACTION READ WRITE requires the CONNECTION_ADMIN privilege (or the deprecated SUPER privilege).

Important

许多用于编写 MySQL 客户端应用程序的 API(例如 JDBC)提供了自己的启动事务方法,这些方法可以(有时也应该)代替客户端发送 START TRANSACTION 语句。有关详细信息,请参阅 第 31 章,Connectors and APIs,或查阅您所用 API 的文档。Many APIs used for writing MySQL client applications (such as JDBC) provide their own methods for starting transactions that can (and sometimes should) be used instead of sending a START TRANSACTION statement from the client. See Chapter 31, Connectors and APIs, or the documentation for your API, for more information.

要显式禁用自动提交模式,请使用以下语句:To disable autocommit mode explicitly, use the following statement:

SET autocommit=0;

通过将 autocommit 变量设置为零来禁用自动提交模式后,对事务安全表(例如 InnoDB 或 NDB 表)的更改不会立即生效。您必须使用 COMMIT 将更改保存到磁盘,或使用 ROLLBACK 忽略更改。After disabling autocommit mode by setting the autocommit variable to zero, changes to transaction-safe tables (such as those for InnoDB or NDB) are not made permanent immediately. You must use COMMIT to store your changes to disk or ROLLBACK to ignore the changes.

autocommit 是会话变量,必须针对每个会话进行设置。要为每个新连接禁用自动提交模式,请参阅 autocommit 系统变量在 第 7.1.8 节,“服务器系统变量” 的描述。autocommit is a session variable and must be set for each session. To disable autocommit mode for each new connection, see the description of the autocommit system variable at Section 7.1.8, “Server System Variables”.

BEGIN 和 BEGIN WORK 被支持作为 START TRANSACTION 的别名,用于启动事务。START TRANSACTION 是标准 SQL 语法,是启动临时事务的推荐方式,并且允许 BEGIN 所不支持的修饰符。BEGIN and BEGIN WORK are supported as aliases of START TRANSACTION for initiating a transaction. START TRANSACTION is standard SQL syntax, is the recommended way to start an ad-hoc transaction, and permits modifiers that BEGIN does not.

BEGIN 语句与用于开始 BEGIN ... END 复合语句的 BEGIN 关键字不同。后者并不开始一个事务。参见 第 15.6.1 节,“BEGIN ... END 复合语句”。The BEGIN statement differs from the use of the BEGIN keyword that starts a BEGIN ... END compound statement. The latter does not begin a transaction. See Section 15.6.1, “BEGIN ... END Compound Statement”.

Note

在所有存储程序(存储过程和函数、触发器和事件)中,解析器将 BEGIN [WORK] 视为 BEGIN ... END 块的开始。在此上下文中启动事务请改为使用 START TRANSACTION。Within all stored programs (stored procedures and functions, triggers, and events), the parser treats BEGIN [WORK] as the beginning of a BEGIN ... END block. Begin a transaction in this context with START TRANSACTION instead.

可选的 WORK 关键字支持用于 COMMIT 和 ROLLBACKCHAIN 和 RELEASE 子句也支持。CHAIN 和 RELEASE可用于对事务完成的额外控制。completion_type 系统变量的值决定了默认的完成行为。参见 第 7.1.8 节,“服务器系统变量”。The optional WORK keyword is supported for COMMIT and ROLLBACK, as are the CHAIN and RELEASE clauses. CHAIN and RELEASE can be used for additional control over transaction completion. The value of the completion_type system variable determines the default completion behavior. See Section 7.1.8, “Server System Variables”.

AND CHAIN 子句会在当前事务结束后立即启动新事务,且新事务的隔离级别与刚刚终止的事务相同。新事务还使用与刚刚终止事务相同的访问模式(READ WRITE 或 READ ONLY)。RELEASE 子句会导致服务器在终止当前事务后断开当前客户端会话。包含 NO 关键字会抑制 CHAIN 或 RELEASE 完成,如果系统变量默认设置为导致链式或释放完成,completion_typeThe AND CHAIN clause causes a new transaction to begin as soon as the current one ends, and the new transaction has the same isolation level as the just-terminated transaction. The new transaction also uses the same access mode (READ WRITE or READ ONLY) as the just-terminated transaction. The RELEASE clause causes the server to disconnect the current client session after terminating the current transaction. Including the NO keyword suppresses CHAIN or RELEASE completion, which can be useful if the completion_type system variable is set to cause chaining or release completion by default.

开始事务会提交任何待处理事务。更多信息请参见 第 15.3.3 节,“导致隐式提交的语句”。Beginning a transaction causes any pending transaction to be committed. See Section 15.3.3, “Statements That Cause an Implicit Commit”, for more information.

开始事务还会导致以 LOCK TABLES的表锁释放,就像你执行了 UNLOCK TABLES。开始事务不会释放通过 FLUSH TABLES WITH READ LOCK“。Beginning a transaction also causes table locks acquired with LOCK TABLES to be released, as though you had executed UNLOCK TABLES. Beginning a transaction does not release a global read lock acquired with FLUSH TABLES WITH READ LOCK.

为了获得最佳效果,事务应仅使用由单个事务安全存储引擎管理的表执行。否则,可能出现以下问题:For best results, transactions should be performed using only tables managed by a single transaction-safe storage engine. Otherwise, the following problems can occur:

  • 如果你使用多个事务安全存储引擎的表(如 InnoDB),且事务隔离层级不是 SERIALIZABLE当一个事务提交时,另一个使用相同表的正在进行的事务只看到第一个事务所做的部分更改。也就是说,混合引擎无法保证事务的原子性,可能导致不一致。(如果混合引擎事务不频繁,你可以根据需要使用 SET TRANSACTION ISOLATION LEVEL 将隔离级别设置为 SERIALIZABLE,按需按每个事务进行。)If you use tables from more than one transaction-safe storage engine (such as InnoDB), and the transaction isolation level is not SERIALIZABLE, it is possible that when one transaction commits, another ongoing transaction that uses the same tables sees only some of the changes made by the first transaction. That is, the atomicity of transactions is not guaranteed with mixed engines and inconsistencies can result. (If mixed-engine transactions are infrequent, you can use SET TRANSACTION ISOLATION LEVEL to set the isolation level to SERIALIZABLE on a per-transaction basis as necessary.)

  • 如果在事务中使用不支持事务的表,则对这些表的更改会立即存储,无论自动提交模式的状态如何。If you use tables that are not transaction-safe within a transaction, changes to those tables are stored at once, regardless of the status of autocommit mode.

  • 如果在事务中更新非事务表后发出ROLLBACK语句,将会出现ER_WARNING_NOT_COMPLETE_ROLLBACK警告。对事务安全表的更改会回滚,但对非事务安全表的更改不会回滚。If you issue a ROLLBACK statement after updating a nontransactional table within a transaction, an ER_WARNING_NOT_COMPLETE_ROLLBACK warning occurs. Changes to transaction-safe tables are rolled back, but not changes to nontransaction-safe tables.

每个事务在COMMIT时作为一个整体存储在二进制日志中。回滚的事务不会被记录。(例外:对非事务表的修改无法回滚。如果回滚的事务包含对非事务表的修改,则整个事务会记录在二进制日志中,并在末尾添加一个ROLLBACK语句,以确保对非事务表的修改被复制。) 参见第 7.4.4 节,“二进制日志”。Each transaction is stored in the binary log in one chunk, upon COMMIT. Transactions that are rolled back are not logged. (Exception: Modifications to nontransactional tables cannot be rolled back. If a transaction that is rolled back includes modifications to nontransactional tables, the entire transaction is logged with a ROLLBACK statement at the end to ensure that modifications to the nontransactional tables are replicated.) See Section 7.4.4, “The Binary Log”.

可以使用SET TRANSACTION语句更改事务的隔离级别或访问模式。参见第 15.3.7 节,“SET TRANSACTION 语句”。You can change the isolation level or access mode for transactions with the SET TRANSACTION statement. See Section 15.3.7, “SET TRANSACTION Statement”.

回滚可能是一个较慢的操作,并且可能隐式发生,而用户并未显式请求(例如,当发生错误时)。因此,SHOW PROCESSLIST在会话的State列中显示Rolling back,不仅适用于使用ROLLBACK语句执行的显式回滚,也适用于隐式回滚。Rolling back can be a slow operation that may occur implicitly without the user having explicitly asked for it (for example, when an error occurs). Because of this, SHOW PROCESSLIST displays Rolling back in the State column for the session, not only for explicit rollbacks performed with the ROLLBACK statement but also for implicit rollbacks.

Note

在 MySQL 8.4 中,BEGIN、COMMIT 和 ROLLBACK 不受 --replicate-do-db 或 --replicate-ignore-db 规则的影响。In MySQL 8.4, BEGIN, COMMIT, and ROLLBACK are not affected by --replicate-do-db or --replicate-ignore-db rules.

当 InnoDB 完整回滚一个事务时,该事务设置的所有锁都会被释放。如果事务中的单条 SQL 语句因错误(例如重复键错误)而回滚,该语句设置的锁会保留,而事务仍然保持活动状态。这是因为 InnoDB 以一种无法事后确定哪个锁是由哪个语句设置的格式存储行锁。When InnoDB performs a complete rollback of a transaction, all locks set by the transaction are released. If a single SQL statement within a transaction rolls back as a result of an error, such as a duplicate key error, locks set by the statement are preserved while the transaction remains active. This happens because InnoDB stores row locks in a format such that it cannot know afterward which lock was set by which statement.

如果事务中的SELECT 语句调用了存储函数,而存储函数内的语句失败,则该语句会回滚。如果随后对事务执行了ROLLBACK,则整个事务将回滚。If a SELECT statement within a transaction calls a stored function, and a statement within the stored function fails, that statement rolls back. If ROLLBACK is executed for the transaction subsequently, the entire transaction rolls back.