MySQL的SQL语句 -事务性语句和锁定语句(1)

事务性语句和锁定语句html

START TRANSACTION、COMMIT 和 ROLLBACKmysql

1. START TRANSACTION
2.     [transaction_characteristic [, transaction_characteristic] ...]
3. 
4. transaction_characteristic: {
5.     WITH CONSISTENT SNAPSHOT
6.   | READ WRITE
7.   | READ ONLY
8. }
9. 
10. BEGIN [WORK]
11. COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
12. ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
13. SET autocommit = {0 | 1}

这些语句提供了对事务使用的控制:sql

● START TRANSACTION 或 BEGIN 启动新事务。安全

● COMMIT 提交当前事务,使其更改永久化。服务器

● ROLLBACK 回滚当前事务,取消其更改。ide

● SET autocommit 将禁用或启用当前会话的默认自动提交模式。函数

默认状况下,MySQL 在自动提交模式下运行。这意味着,若是不是在事务内部,每一个语句都是原子的,就好像它被 START TRANSACTION 和 COMMIT 包围同样。不能使用 ROLLBACK 撤消效果;可是,若是在语句执行过程当中发生错误,语句将回滚。优化

要隐式禁用一系列单个语句的自动提交模式,请使用 START TRANSACTION 语句:日志

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

使用 START TRANSACTION,自动提交保持禁用状态,直到使用 COMMIT 或 ROLLBACK 结束事务。而后,自动提交模式将恢复到之前的状态。code

START TRANSACTION 容许多个修饰符控制事务特征。要指定多个修饰符,请用逗号分隔它们。

● WITH CONSISTENT SNAPSHOT 修饰符为支持一致性读取的存储引擎启动一致性读取。这只适用于 InnoDB。其效果与发出 START TRANSACTION 指令,而后从任何 InnoDB 表中执行 SELECT 同样。WITH CONSISTENT SNAPSHOT 修饰符不会更改当前事务隔离级别,所以仅当当前隔离级别容许一致读取时,它才提供一致的快照。惟一容许一致读取的隔离级别是 REPEATABLE READ。全部其余隔离级别,将忽略 WITH CONSISTENT SNAPSHOT 子句。忽略 WITH CONSISTENT SNAPSHOT 子句时,将生成警告。

● READ WRITE 和 READ ONLY 修饰符设置事务访问模式。它们容许或禁止对事务中使用的表进行更改。READ ONLY 阻止事务修改或锁定对其余事务可见的事务表和非事务表;事务仍然能够修改或锁定临时表。

当已知事务为只读时,MySQL 支持对 InnoDB 表的查询进行额外优化。指定 READ ONLY 可确保在没法自动肯定只读状态的状况下应用这些优化。

若是未指定访问模式,则应用默认模式。除非默认值已更改,不然为读/写。不容许在同一语句中同时指定 READ WRITE 和 READ ONLY。

在只读模式下,仍然可使用 DML 语句更改用 TEMPORARY 关键字建立的表。但不容许使用 DDL 语句进行更改。

若是启用 read_only 系统变量,则使用 START TRANSACTION READ WRITE 显式启动事务须要 CONNECTION_ADMIN 权限(或不推荐使用的 SUPER 权限)。

重要

许多用于编写 MySQL 客户端应用程序的 API (如JDBC)提供了本身的启动事务的方法,可使用这些方法(有时也应该),而不是从客户端发送 START TRANSACTION 语句。

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

1. SET autocommit=0;

经过将 autocommit 变量设置为零来禁用自动提交模式后,对事务安全表(如 InnoDB 或 NDB 的表)的更改不会当即永久化。必须使用 COMMIT 才能将更改存储到磁盘,或使用 ROLLBACK 放弃更改。

autocommit 是一个会话变量,必须为每一个会话单独设置。

BEGIN 和 BEGIN WORK 做为 START TRANSACTION 的别名受到支持,用于启动事务。START TRANSACTION 是标准的 SQL 语法,是启动特定事务的推荐方法,而且容许使用 BEGIN 不支持的修饰符。

BEGIN 语句不一样于使用 BEGIN 关键字来启动 BEGIN ... END 的复合语句,后者不启动事务。

注意

在全部存储程序(存储过程和函数、触发器和事件)中,解析器将 BEGIN [WORK] 视为 BEGIN ... END 块的开始。在这个上下文中用 START TRANSACTION 开始事务。

COMMIT 和 ROLLBACK 支持可选的 WORK 关键字,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 警告。回滚对事务安全表的更改,但不会回滚对非事务安全表的更改。

提交时,每一个事务都存储在二进制日志中的一个块中。不会记录回滚的事务。(例外:没法回滚对非事务表的修改。若是回滚的事务包括对非事务表的修改,则整个事务将在结尾使用 ROLLBACK 语句进行记录,以确保复制对非事务表的修改。)

可使用 SET TRANSACTION 语句更改事务的隔离级别或访问模式。

回滚多是一个缓慢的操做,可能在用户没有明确请求的状况下隐式发生(例如,当发生错误时)。所以,SHOW PROCESSLIST 在会话的 State 列中显示 Rolling back,这不只用于使用 ROLLBACK 语句执行的显式回滚,还包括隐式回滚。

注意

在 MySQL 8.0 中,BEGIN、COMMIT 和 ROLLBACK 不受 --replicate-do-db 或 --replicate-ignore-db 规则的影响。

当 InnoDB 执行事务的彻底回滚时,该事务设置的全部锁都会被释放。若是事务中的单个 SQL 语句因为错误(如重复键错误)而回滚,则在事务保持活动状态的同时保留由该语句设置的锁。发生这种状况是由于 InnoDB 以一种格式存储行锁,它没法知道哪个锁是由哪一个语句设置的。

若是事务中的 SELECT 语句调用存储函数,而存储函数中的语句失败,则该语句将回滚。若是随后对事务执行 ROLLBACK,则整个事务回滚。

官方网址:
https://dev.mysql.com/doc/refman/8.0/en/commit.html