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 TRANSACTION
或BEGIN
开始新交易。COMMIT
提交当前事务,使其更改永久生效。ROLLBACK
回滚当前事务,取消其更改。SET autocommit
禁用或启用当前会话的默认自动提交模式。
默认情况下,MySQL在启用自动提交模式的情况下运行。这意味着,当不在事务内时,每个语句都是原子的,就像它被START TRANSACTION
和包围一样COMMIT
。您不能ROLLBACK
用来撤消效果。但是,如果在语句执行期间发生错误,则会回滚该语句。
要隐式禁用单个语句系列的自动提交模式,请使用以下START TRANSACTION
语句:
START TRANSACTION ;SELECT @A:=SUM(salary)FROM table1WHERE type =1;UPDATE table2SET summary=@AWHERE type =1;COMMIT ;
使用时START TRANSACTION
,自动提交保持禁用状态,直到您使用COMMIT
或结束事务ROLLBACK
。然后,自动提交模式将恢复为之前的状态。
START TRANSACTION
允许使用几个修饰符来控制交易特征。要指定多个修饰符,请用逗号分隔。
- 该
WITH CONSISTENT SNAPSHOT
修正开始一致读取存储引擎,能够它。这仅适用于InnoDB
。其效果与从任何表中发出aSTART TRANSACTION
后跟a 相同。请参见“一致的非锁定读取”。该修改不改变当前的事务隔离级别,所以它提供了一个一致的快照仅在当前隔离级别是一个允许连续读取。允许一致读取的唯一隔离级别是。对于所有其他隔离级别,SELECT
InnoDB
WITH CONSISTENT SNAPSHOT
REPEATABLE READ
WITH CONSISTENT SNAPSHOT
子句被忽略。WITH CONSISTENT SNAPSHOT
子句被忽略时会生成警告。 在
READ WRITE
与READ ONLY
修饰符设置事务访问模式。它们允许或禁止更改事务中使用的表。该READ ONLY
限制可防止事务修改或锁定其他事务可见的事务表和非事务表。事务仍然可以修改或锁定临时表。InnoDB
当已知事务是只读的时, MySQL为表查询提供了额外的优化。通过指定READ ONLY
可确保在无法自动确定只读状态的情况下应用这些优化。有关更多信息,请参见“优化InnoDB只读事务”。如果未指定访问模式,则应用默认模式。除非更改了默认值,否则它是读/写的。不允许在同一语句中同时指定
READ WRITE
和READ ONLY
。在只读模式下,仍然可以
TEMPORARY
使用DML语句更改用关键字创建的表。与永久表一样,不允许使用DDL语句进行更改。有关事务访问模式的其他信息,包括更改默认模式的方法,请参见“ SET TRANSACTION语句”。
如果
read_only
系统变量被启用,明确启动事务与START TRANSACTION READ WRITE
需要CONNECTION_ADMIN
或SUPER
特权。
重要许多用于编写MySQL客户端应用程序的API(例如JDBC)提供了自己的启动事务的方法,这些方法可以(有时应该)用于代替
START TRANSACTION
从客户端发送语句。有关更多信息,请参见连接器和API或API文档。
要显式禁用自动提交模式,请使用以下语句:
SET autocommit=0;
通过将autocommit
变量设置为零来禁用自动提交模式之后,对事务安全表(例如for InnoDB
或NDB
)的更改不会立即变为永久更改。您必须使用COMMIT
将更改存储到磁盘或ROLLBACK
忽略更改。
autocommit
是会话变量,必须为每个会话设置。要为每个新连接禁用自动提交模式,请参见“服务器系统变量”中对autocommit
系统变量的描述。
BEGIN
并且BEGIN WORK
作为START TRANSACTION
启动事务的别名而受支持。START TRANSACTION
是标准的SQL语法,是启动临时事务的推荐方法,并且允许使用BEGIN
不允许的修饰符。
该BEGIN
语句与BEGIN
启动BEGIN ... END
复合语句的关键字的用法不同。后者不开始交易。请参见“ BEGIN ... END复合语句”。
注意在所有存储的程序(存储的过程和函数,触发器和事件)中,解析器将其
BEGIN[WORK]
视为BEGIN ... END
块的开始。START TRANSACTION
而是在这种情况下开始事务。
和和子句一样,对和WORK
支持可选关键字。并且可以用于对交易完成的其他控制。系统变量的值确定默认的完成行为。请参见“服务器系统变量”。COMMIT
ROLLBACK
CHAIN
RELEASE
CHAIN
RELEASE
completion_type
该AND CHAIN
子句使新事务在当前事务结束时立即开始,并且新事务具有与刚刚终止的事务相同的隔离级别。新事务还使用与刚刚终止的事务相同的访问模式(READ WRITE
或READ ONLY
)。该RELEASE
子句使服务器在终止当前事务之后断开当前客户端会话的连接。包括NO
关键字抑制CHAIN
或RELEASE
完成,如果completion_type
默认情况下将系统变量设置为导致链接或释放完成,则这很有用。
开始事务会导致任何未决事务被提交。
开始事务也会导致所获取的表锁LOCK TABLES
被释放,就像您已执行一样UNLOCK TABLES
。开始事务不会释放通过获取的全局读取锁FLUSH TABLES WITH READ LOCK
。
为了获得最佳结果,应仅使用由单个事务安全存储引擎管理的表来执行事务。否则,可能会出现以下问题:
- 如果您使用来自多个事务安全存储引擎(例如
InnoDB
)的表,而事务隔离级别不是SERIALIZABLE
,则当一个事务提交时,使用同一表的另一个正在进行的事务可能仅会看到一些更改。由第一笔交易完成。也就是说,使用混合引擎无法保证事务的原子性,并且可能导致不一致。(如果很少使用混合引擎事务,则可以根据SET TRANSACTION ISOLATION LEVEL
需要将隔离级别设置为SERIALIZABLE
基于每个事务。) - 如果在事务中使用不安全事务的表,则无论自动提交模式的状态如何,都将立即存储对这些表的更改。
- 如果
ROLLBACK
在更新事务中的非事务表之后发出语句,ER_WARNING_NOT_COMPLETE_ROLLBACK
则会发生警告。回滚对事务安全表的更改,但不回滚对非事务安全表的更改。
每笔交易均以块的形式存储在二进制日志中COMMIT
。回滚的事务不会被记录。(例外:不能回滚对非事务处理表的修改。如果回滚的事务包括对非事务处理表的修改,则整个事务记录ROLLBACK
在末尾,以确保复制对非事务处理表的修改。)请参见本节。 5.4.4,“二进制日志”。
您可以使用该SET TRANSACTION
语句更改事务的隔离级别或访问模式。请参见“ SET TRANSACTION语句”。
回滚可能是一个缓慢的操作,可能会隐式发生,而无需用户明确要求(例如,发生错误时)。正因为如此,SHOW PROCESSLIST
显示Rolling back
在State
该会话列,不仅与进行明确回滚ROLLBACK
语句,但也隐式回滚。
在MySQL 8.0,,BEGIN
,COMMIT
和ROLLBACK
不受--replicate-do-db
或--replicate-ignore-db
规则。
无法回滚的语句
某些语句无法回滚。通常,这些语句包括数据定义语言(DDL)语句,例如创建或删除数据库的语句,创建,删除或更改表或存储例程的语句。
您应设计您的交易不包含此类声明。如果您在无法回滚的事务中早期发出了一个语句,然后又有另一个语句失败,则在这种情况下,通过发出一条ROLLBACK
语句无法回滚事务的全部效果。
导致隐式提交的语句
本节中列出的语句(以及它们的所有同义词)隐式结束当前会话中任何活动的事务,就像您COMMIT
在执行该语句之前进行了操作一样。
这些语句中的大多数还会在执行后导致隐式提交。目的是在其自己的特殊事务中处理每个这样的语句。事务控制和锁定语句是例外:如果隐式提交发生在执行之前,则另一个不会发生在执行之后。
定义或修改数据库对象的数据定义语言(DDL)语句。
ALTER EVENT
,ALTER FUNCTION
,ALTER PROCEDURE
,ALTER SERVER
,ALTER TABLE
,ALTER VIEW
,CREATE DATABASE
,CREATE EVENT
,CREATE FUNCTION
,CREATE INDEX
,CREATE PROCEDURE
,CREATE ROLE
,CREATE SERVER
,CREATE SPATIAL REFERENCE SYSTEM
,CREATE TABLE
,CREATE TRIGGER
,CREATE VIEW
,DROP DATABASE
,DROP EVENT
,DROP FUNCTION
,DROP INDEX
,DROP PROCEDURE
,DROP ROLE
,DROP SERVER
,DROP SPATIAL REFERENCE SYSTEM
,DROP TABLE
,DROP TRIGGER
,DROP VIEW
,INSTALL PLUGIN
,RENAME TABLE
,TRUNCATE TABLE
,UNINSTALL PLUGIN
。CREATE TABLE
而DROP TABLE
如果语句不提交事务TEMPORARY
时使用的关键字。(这不适用于确实引起提交的临时表(例如ALTER TABLE
和)上的其他操作CREATE INDEX
。)尽管没有发生隐式提交,但也无法回滚该语句,这意味着使用此类语句会导致事务性原子化。被侵犯。例如,如果使用CREATE TEMPORARY TABLE
然后回滚事务,则该表仍然存在。中的
CREATE TABLE
语句InnoDB
作为单个事务处理。这意味着ROLLBACK
来自用户的a 不会撤消CREATE TABLE
用户在该事务期间所做的语句。CREATE TABLE ... SELECT
在创建非临时表时,在执行语句之前和之后导致隐式提交。(没有提交CREATE TEMPORARY TABLE ... SELECT
。)- 隐式使用或修改
mysql
数据库中表的语句。ALTER USER
,CREATE USER
,DROP USER
,GRANT
,RENAME USER
,REVOKE
,SET PASSWORD
。 事务控制和锁定语句。
BEGIN
,LOCK TABLES
,SET autocommit = 1
(如果该值不是1),,。START TRANSACTION
UNLOCK TABLES
UNLOCK TABLES
仅LOCK TABLES
当当前已锁定任何表以获取非事务性表锁时,才提交事务。由于后面的语句不获取表级锁,因此不会进行UNLOCK TABLES
后续的提交FLUSH TABLES WITH READ LOCK
。事务不能嵌套。这是由于在发出
START TRANSACTION
语句或其同义词之一时对任何当前事务执行隐式提交的结果。当事务处于
ACTIVE
状态时,不能在XA事务中使用导致隐式提交的语句。该
BEGIN
语句与BEGIN
启动BEGIN ... END
复合语句的关键字的用法不同。后者不会导致隐式提交。请参见“ BEGIN ... END复合语句”。- 数据加载语句。
LOAD DATA
。LOAD DATA
仅对使用NDB
存储引擎的表导致隐式提交。 - 行政声明。
ANALYZE TABLE
,CACHE INDEX
,CHECK TABLE
,FLUSH
,LOAD INDEX INTO CACHE
,OPTIMIZE TABLE
,REPAIR TABLE
,RESET
(但不是RESET PERSIST
)。 - 复制控制语句。
START SLAVE
,STOP SLAVE
,RESET SLAVE
,CHANGE MASTER TO
。