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 TRANSACTIONorBEGINstart a new transaction.COMMIT提交当前事务,使其更改永久生效。COMMITcommits the current transaction, making its changes permanent.ROLLBACK回滚当前事务,取消其更改。ROLLBACKrolls back the current transaction, canceling its changes.SET autocommit禁用或启用当前会话的默认自动提交模式。SET autocommitdisables 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。TheWITH CONSISTENT SNAPSHOTmodifier starts a consistent read for storage engines that are capable of it. This applies only toInnoDB. The effect is the same as issuing aSTART TRANSACTIONfollowed by aSELECTfrom anyInnoDBtable. See Section 17.7.2.3, “Consistent Nonlocking Reads”. TheWITH CONSISTENT SNAPSHOTmodifier 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 isREPEATABLE READ. For all other isolation levels, theWITH CONSISTENT SNAPSHOTclause is ignored. A warning is generated when theWITH CONSISTENT SNAPSHOTclause is ignored.READ WRITE和READ ONLY修饰符设置事务访问模式。它们允许或禁止对事务中使用的表进行更改。READ ONLY限制防止事务修改或锁定对其他事务可见的事务表和非事务表;事务仍可修改或锁定临时表。TheREAD WRITEandREAD ONLYmodifiers set the transaction access mode. They permit or prohibit changes to tables used in the transaction. TheREAD ONLYrestriction 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 onInnoDBtables when the transaction is known to be read-only. SpecifyingREAD ONLYensures 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 bothREAD WRITEandREAD ONLYin the same statement.在只读模式下,仍可使用 DML 语句更改使用
TEMPORARY。不允许对 DDL 语句进行更改,与永久表相同。In read-only mode, it remains possible to change tables created with theTEMPORARYkeyword 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 theread_onlysystem variable is enabled, explicitly starting a transaction withSTART TRANSACTION READ WRITErequires theCONNECTION_ADMINprivilege (or the deprecatedSUPERprivilege).
许多用于编写 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”.
在所有存储程序(存储过程和函数、触发器和事件)中,解析器将 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 asInnoDB), and the transaction isolation level is notSERIALIZABLE, 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 useSET TRANSACTION ISOLATION LEVELto set the isolation level toSERIALIZABLEon 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 aROLLBACKstatement after updating a nontransactional table within a transaction, anER_WARNING_NOT_COMPLETE_ROLLBACKwarning 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.
在 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.