13.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}
这些语句可控制transactions的使用:
-
START TRANSACTION
或BEGIN
开始新 Transaction。 -
COMMIT
提交当前事务,使其更改永久生效。 -
ROLLBACK
回滚当前事务,取消其更改。 -
SET autocommit
禁用或启用当前会话的默认自动提交模式。
默认情况下,MySQL 在启用autocommit模式的情况下运行。这意味着,当不在事务内时,每个语句都是原子的,就像被START TRANSACTION
和COMMIT
包围一样。您不能使用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
时,自动提交保持禁用状态,直到您以COMMIT
或ROLLBACK
结束事务。然后,自动提交模式将恢复为之前的状态。
START TRANSACTION
允许几个修饰符来控制 TransactionFeature。要指定多个修饰符,请用逗号分隔。
-
WITH CONSISTENT SNAPSHOT
修饰符为具有此功能的存储引擎启动consistent read。这仅适用于InnoDB
。效果与在任何InnoDB
table 中发出START TRANSACTION
,然后发出SELECT的效果相同。参见第 14.7.2.3 节“一致的非锁定读取”。WITH CONSISTENT SNAPSHOT
修饰符不会更改当前事务isolation level,因此仅当当前隔离级别为允许一致读取的级别时,它才会提供一致的快照。允许一致读取的唯一隔离级别是REPEATABLE READ。对于所有其他隔离级别,将忽略WITH CONSISTENT SNAPSHOT
子句。从 MySQL 5.7.2 开始,忽略WITH CONSISTENT SNAPSHOT
子句会生成警告。 -
READ WRITE
和READ ONLY
修饰符设置事务访问模式。它们允许或禁止更改事务中使用的 table。READ ONLY
限制防止事务修改或锁定其他事务可见的事务 table 和非事务 table;事务仍然可以修改或锁定临时 table。
当已知事务为只读时,MySQL 会对InnoDB
table 上的查询启用额外的优化。指定READ ONLY
可以确保在无法自动确定只读状态的情况下应用这些优化。有关更多信息,请参见第 8.5.3 节“优化 InnoDB 只读事务”。
如果未指定访问模式,则应用默认模式。除非更改了默认值,否则它是读/写的。不允许在同一语句中同时指定READ WRITE
和READ ONLY
。
在只读模式下,仍然可以使用 DML 语句更改用TEMPORARY
关键字创建的 table。与永久 table 一样,不允许使用 DDL 语句进行更改。
有关事务访问模式的其他信息,包括更改默认模式的方法,请参见第 13.3.6 节“ SET TRANSACTION 语句”。
如果启用了read_only系统变量,则以START TRANSACTION READ WRITE
显式启动事务需要SUPER特权。
Important
许多用于编写 MySQLClient 端应用程序的 API(例如 JDBC)提供了自己的启动事务的方法,这些方法可以(有时应该)用来代替从 Client 端发送START TRANSACTION
语句。有关更多信息,请参见第 27 章,连接器和 API或 API 文档。
要显式禁用自动提交模式,请使用以下语句:
SET autocommit=0;
通过将autocommit变量设置为零来禁用自动提交模式之后,对事务安全 table(例如InnoDB或NDB的 table)的更改不会立即变为永久不变。您必须使用COMMIT将更改存储到磁盘上,或使用ROLLBACK
忽略更改。
autocommit是会话变量,必须为每个会话设置。要为每个新连接禁用自动提交模式,请参见第 5.1.7 节“服务器系统变量”处的autocommit系统变量的描述。
支持BEGIN
和BEGIN WORK
作为START TRANSACTION
的别名以启动事务。 START TRANSACTION
是标准的 SQL 语法,是启动临时事务的推荐方法,并且允许BEGIN
不允许的修饰符。
BEGIN
语句不同于使用BEGIN
关键字来启动开始...结束复合语句。后者不开始 Transaction。参见第 13.6.1 节“ BEGIN ... END 复合语句”。
Note
在所有存储的程序(存储的过程和函数,触发器和事件)中,解析器将BEGIN [WORK]
视为开始...结束块的开头。在这种情况下,请改用START TRANSACTION开始 Transaction。
COMMIT
和ROLLBACK
支持可选的WORK
关键字,CHAIN
和RELEASE
子句也受支持。 CHAIN
和RELEASE
可用于对事务完成进行附加控制。 completion_type系统变量的值确定默认的完成行为。参见第 5.1.7 节“服务器系统变量”。
AND CHAIN
子句使新事务在当前事务结束时立即开始,并且新事务具有与刚刚终止的事务相同的隔离级别。新事务还使用与刚刚终止的事务相同的访问模式(READ WRITE
或READ ONLY
)。 RELEASE
子句使服务器在终止当前事务之后断开当前 Client 端会话的连接。包含NO
关键字将禁止CHAIN
或RELEASE
完成,如果将completion_type系统变量设置为默认导致链接或释放完成,则这很有用。
开始事务将导致任何未决事务被提交。有关更多信息,请参见第 13.3.3 节“导致隐式提交的声明”。
开始事务也会导致用LOCK TABLES获取的 table 锁被释放,就好像您已执行UNLOCK TABLES一样。开始事务不会释放通过带读取锁的平桌子获取的全局读取锁。
为了获得最佳结果,应该仅使用由单个事务安全存储引擎 Management 的 table 来执行事务。否则,可能会出现以下问题:
-
如果您使用来自多个事务安全存储引擎(例如
InnoDB
)的 table,并且事务隔离级别不是SERIALIZABLE,则当一个事务提交时,使用相同 table 的另一个正在进行的事务可能只会看到其中一些。第一笔 Transaction 所做的更改。也就是说,使用混合引擎无法保证事务的原子性,并且可能导致不一致。 (如果不经常使用混合引擎事务,则可以根据需要使用设置 Transaction 隔离级别将每个事务的隔离级别设置为SERIALIZABLE。) -
如果您在事务中使用不安全事务的 table,则无论自动提交模式的状态如何,都将立即存储对这些 table 的更改。
-
如果在更新事务中的非事务 table 之后发出ROLLBACK语句,则会出现ER_WARNING_NOT_COMPLETE_ROLLBACK警告。回滚对事务安全 table 的更改,但不回滚对非事务安全 table 的更改。
每个事务都在COMMIT上以一个块的形式存储在二进制日志中。回滚的事务不会记录。 ( exception :无法回滚对非事务处理 table 的修改.如果回滚的事务包括对非事务处理 table 的修改,则整个事务都将在末尾使用ROLLBACK语句记录下来,以确保对非事务处理 table 的修改被复制)。请参见第 5.4.4 节“二进制日志”。
您可以使用SET TRANSACTION语句更改事务的隔离级别或访问模式。参见第 13.3.6 节“ SET TRANSACTION 语句”。
回滚可能是一个缓慢的操作,可能会隐式发生,而无需用户明确要求(例如,发生错误时)。因此,SHOW PROCESSLIST在会话的State
列中显示Rolling back
,不仅用于使用ROLLBACK语句执行的显式回滚,而且还用于隐式回滚。
Note
在 MySQL 5.7 中,BEGIN
,COMMIT
和ROLLBACK
不受--replicate-do-db或--replicate-ignore-db规则的影响。