• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 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 TRANSACTIONBEGIN开始新交易。
    • COMMIT提交当前事务,使其更改永久生效。
    • ROLLBACK回滚当前事务,取消其更改。
    • SET autocommit禁用或启用当前会话的默认自动提交模式。

    默认情况下,MySQL在启用自动提交模式的情况下运行。这意味着,当不在事务内时,每个语句都是原子的,就像它被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允许使用几个修饰符来控制交易特征。要指定多个修饰符,请用逗号分隔。

    • WITH CONSISTENT SNAPSHOT修正开始一致读取存储引擎,能够它。这仅适用于InnoDB。其效果与从任何表中发出a START TRANSACTION后跟a 相同。请参见“一致的非锁定读取”。该修改不改变当前的事务隔离级别,所以它提供了一个一致的快照仅在当前隔离级别是一个允许连续读取。允许一致读取的唯一隔离级别是。对于所有其他隔离级别,SELECTInnoDBWITH CONSISTENT SNAPSHOTREPEATABLE READWITH CONSISTENT SNAPSHOT子句被忽略。WITH CONSISTENT SNAPSHOT子句被忽略时会生成警告。
    • READ WRITEREAD ONLY修饰符设置事务访问模式。它们允许或禁止更改事务中使用的表。该READ ONLY限制可防止事务修改或锁定其他事务可见的事务表和非事务表。事务仍然可以修改或锁定临时表。

      InnoDB当已知事务是只读的时, MySQL为表查询提供了额外的优化。通过指定READ ONLY可确保在无法自动确定只读状态的情况下应用这些优化。有关更多信息,请参见“优化InnoDB只读事务”。

      如果未指定访问模式,则应用默认模式。除非更改了默认值,否则它是读/写的。不允许在同一语句中同时指定READ WRITEREAD ONLY

      在只读模式下,仍然可以TEMPORARY使用DML语句更改用关键字创建的表。与永久表一样,不允许使用DDL语句进行更改。

      有关事务访问模式的其他信息,包括更改默认模式的方法,请参见“ SET TRANSACTION语句”。

      如果read_only系统变量被启用,明确启动事务与START TRANSACTION READ WRITE需要CONNECTION_ADMINSUPER特权。

    重要

    许多用于编写MySQL客户端应用程序的API(例如JDBC)提供了自己的启动事务的方法,这些方法可以(有时应该)用于代替START TRANSACTION从客户端发送语句。有关更多信息,请参见连接器和APIAPI文档。

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

    SET autocommit=0;
    

    通过将autocommit变量设置为零来禁用自动提交模式之后,对事务安全表(例如for InnoDBNDB)的更改不会立即变为永久更改。您必须使用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支持可选关键字。并且可以用于对交易完成的其他控制。系统变量的值确定默认的完成行为。请参见“服务器系统变量”。COMMITROLLBACKCHAINRELEASECHAINRELEASEcompletion_type

    AND CHAIN子句使新事务在当前事务结束时立即开始,并且新事务具有与刚刚终止的事务相同的隔离级别。新事务还使用与刚刚终止的事务相同的访问模式(READ WRITEREAD ONLY)。该RELEASE子句使服务器在终止当前事务之后断开当前客户端会话的连接。包括NO关键字抑制CHAINRELEASE完成,如果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 backState该会话列,不仅与进行明确回滚ROLLBACK语句,但也隐式回滚。

    注意

    在MySQL 8.0,,BEGINCOMMITROLLBACK不受--replicate-do-db--replicate-ignore-db规则。


    无法回滚的语句

    某些语句无法回滚。通常,这些语句包括数据定义语言(DDL)语句,例如创建或删除数据库的语句,创建,删除或更改表或存储例程的语句。

    您应设计您的交易不包含此类声明。如果您在无法回滚的事务中早期发出了一个语句,然后又有另一个语句失败,则在这种情况下,通过发出一条ROLLBACK语句无法回滚事务的全部效果。

    导致隐式提交的语句

    本节中列出的语句(以及它们的所有同义词)隐式结束当前会话中任何活动的事务,就像您COMMIT在执行该语句之前进行了操作一样。

    这些语句中的大多数还会在执行后导致隐式提交。目的是在其自己的特殊事务中处理每个这样的语句。事务控制和锁定语句是例外:如果隐式提交发生在执行之前,则另一个不会发生在执行之后。

    • 定义或修改数据库对象的数据定义语言(DDL)语句。ALTER EVENTALTER FUNCTIONALTER PROCEDUREALTER SERVERALTER TABLEALTER VIEWCREATE DATABASECREATE EVENTCREATE FUNCTIONCREATE INDEXCREATE PROCEDURECREATE ROLECREATE SERVERCREATE SPATIAL REFERENCE SYSTEMCREATE TABLECREATE TRIGGERCREATE VIEWDROP DATABASEDROP EVENTDROP FUNCTIONDROP INDEXDROP PROCEDUREDROP ROLEDROP SERVERDROP SPATIAL REFERENCE SYSTEMDROP TABLEDROP TRIGGERDROP VIEWINSTALL PLUGINRENAME TABLETRUNCATE TABLEUNINSTALL PLUGIN

      CREATE TABLEDROP 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 USERCREATE USERDROP USERGRANTRENAME USERREVOKESET PASSWORD
    • 事务控制和锁定语句。BEGINLOCK TABLESSET autocommit = 1(如果该值不是1),,。START TRANSACTIONUNLOCK TABLES

      UNLOCK TABLESLOCK TABLES当当前已锁定任何表以获取非事务性表锁时,才提交事务。由于后面的语句不获取表级锁,因此不会进行UNLOCK TABLES后续的提交FLUSH TABLES WITH READ LOCK

      事务不能嵌套。这是由于在发出START TRANSACTION语句或其同义词之一时对任何当前事务执行隐式提交的结果。

      当事务处于ACTIVE状态时,不能在XA事务中使用导致隐式提交的语句。

      BEGIN语句与BEGIN启动BEGIN ... END复合语句的关键字的用法不同。后者不会导致隐式提交。请参见“ BEGIN ... END复合语句”。

    • 数据加载语句。LOAD DATALOAD DATA仅对使用NDB存储引擎的表导致隐式提交。
    • 行政声明。ANALYZE TABLECACHE INDEXCHECK TABLEFLUSHLOAD INDEX INTO CACHEOPTIMIZE TABLEREPAIR TABLERESET(但不是RESET PERSIST)。
    • 复制控制语句。START SLAVESTOP SLAVERESET SLAVECHANGE MASTER TO