Mysql笔记-事务

时间:2022-10-12 15:55:39


事务

事务(Transaction)会把数据库从一种一致状态转换为另一种一致状态。在数据库提交工作时,要么所有修改都已经保存了,要么修改都不保存。

事务是访问并更新数据库中各种数据项的一个程序执行单元。在执行中要么都做修改,要么都不做修改。

InnoDB存储引擎中的事务完全符合ACID的特性。

l  原子性(atomicity)

原子性是指整个数据库事务是不可分割的工作单元。只有使事务中所有的数据库操作都执行成功,才算整个事务成功。事务中任何一个sql语句执行失败,已经执行成功的sql语句必须撤销,数据库的状态必须退回到执行事务前的状态。

l  一致性(consistency)

一致性是指事务将数据库从一种状态转换为下一种一致状态。也就是说,在事务开始之前和事务结束之后,数据库的完整性约束没有被破坏。

l  隔离性(isolation)

隔离性(或称为锁、可串行化和并发控制)。事务的隔离性要求每个读写事务的对象对其他事务的操作对象能相互分离,即该事务提交之前对其他事务都不可见,通常使用锁来实现。

l  持久性(durability)

事务一旦提交,其结果就是永久的。

扁平事务

在扁平事务中,所有的操作都处于同一层次,其有begin work开始,由commit work 或者 rollback work结束。期间的操作是原子的,要么都执行,要么都回滚。

带有保存点的事务

除了支持扁平事务支持的事务之外,允许在事务执行过程中回滚到同一事物较早的一个状态。这是因为某些事务可能在执行过程中出现的错误并不会导致所有的错误都无效,放弃整个事务开销太大。保存点用来通知系统应该记住事务当前的状态,以便当发生错误时,事务能回到保存点当时的状态。

链事务

链事务可以视为保存点模式的一种变种。带有保存点的扁平事务,当系统崩溃时,所有保存点都将消失。这意味着当经行恢复时,事务需要从开始处重新执行,而不能从最近一个保存点继续执行。

链事务的思想是:在提交一个事务时,释放不需要的数据对象,将必要的处理上下文隐式地传递给下一个事务。注意:提交事务操作和下一个事务操作将合并为一个原子操作。

 

嵌套事务

由一个顶层事务控制各个层次的事务。顶层事务之下的事务称为子事务,其控制每一个局部变化。

 

嵌套事务是由若干事务组成的一棵树,子树既可以是嵌套事务,也可以是扁平事务。

处在叶节点的事务是扁平事务。但是每个子事务到叶节点的距离可以不一样。

子事务既可以提交也可以回滚。但是它的提交操作并不会马上生效,除非其父事务已经提交。因此可以说,任何子事务都是在顶层事务提交后才真正提交的。

树中的任意一个事物的回滚会引起它的所有子事务的一同回滚,即子事务不具有持久性。

 

分布事务

通常是一个在分布式环境下运行的扁平事务,因此需要根据数据所在位置访问网络中不同的节点。

事务控制语句

START TRANSACTION | BEGIN [WORK]

COMMIT [WORK] [AND [NO] CHAIN][[NO] RELEASE]

ROLLBACK [WORK] [AND [NO] CHAIN][[NO] RELEASE]

SET AUTOCOMMIT = {0 | 1}

l  START TRANSACTION | BEGIN:显示地开启一个事务

l  COMMIT: commit会提交事务,并使得已对数据库做的所有修改成为永久性的。

l  ROLLBACK:回滚会结束用户的事务,并撤销正在经行的所有未提交的修改。

l  SAVEPOINT identify:SAVEPOINT允许在事务中创建一个保存点,一个事务中可以有多个SAVEPOINT。

l  RELEASE SAVEPOINT identify:删除一个事务的保存点,当没有一个保存点执行这句话时,会抛出一个异常。

l  ROLLBACK TO [SAVEPOINT]identify:可以把事务回滚到标记点,而不回滚在此标记之前的任何工作。

l  SET TRANSACTION:这个语句用来设置事物的隔离级别。InnoDB存储引擎提供的事务隔离级别:READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ、SERILIZABLE。

自选的WORK关键词被支持,用于COMMIT和RELEASE,与CHAIN和RELEASE子句。CHAIN和RELEASE可以被用于对事务完成进行附加控制。Completion_type系统变量的值决定了默认完成的性质。

AND CHAIN子句会在当前事务结束时,立刻启动一个新事务,并且新事务与刚结束的事务有相同的隔离等级。RELEASE子句在终止了当前事务后,会让服务器断开与当前客户端的连接。包含NO关键词可以抑制CHAIN或RELEASE完成。如果completion_type系统变量被设置为一定的值,使连锁或释放完成可以默认进行,此时NO关键词有用。

注意:completion_type默认为0,表示没有任何操作。在这种情况下COMMIT和COMMIT WORK是完全等价的。当参数设置为completion_type的值为1,COMMIT WORK等同于COMMITAND CHAIN,表示马上自动开启一个相同隔离级别的事务。参数completion_type为2时,commit work等同于commitand release,在事务提交后会自动断开与服务器的连接。

ROLLBACK 和 ROLLBACK WORK 与COMMIT 和COMMIT WORK的工作一样。

 

[sql] ​​view plain​​​ ​​copy​​
1. mysql> select@@completion_type\G
2. ***************************1. row ***************************
3. @@completion_type:NO_CHAIN
4. 1 row in set (0.00sec)
5. mysql> set@@completion_type=1;
6. Query OK, 0 rowsaffected (0.00 sec)
7. mysql> select@@completion_type\G
8. ***************************1. row ***************************
9. @@completion_type:CHAIN
10. 1 row in set (0.00sec)
11. mysql> set@@completion_type=2;
12. Query OK, 0 rowsaffected (0.00 sec)
13.
14. mysql> select@@completion_type\G
15. ***************************1. row ***************************
16. @@completion_type:RELEASE
17. 1 row in set (0.00sec)

 

注意:ROLLBACKTO SAVEPOINT,虽然有ROLLBACK,但其实并不是真正地结束一个事务,因此即使执行了ROLLBACK TO SAVEPOINT,之后也需要显示地运行COMMIT或ROLLBACK。

事务隔离级别

SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。

相关语句:

1.查看当前会话隔离级别

 

[sql] ​​view plain​​​ ​​copy​​
1. select @@tx_isolation;

2.查看系统当前隔离级别

 

[sql] ​​view plain​​​ ​​copy​​
1. select @@global.tx_isolation;

3.设置当前会话隔离级别

 


[sql] ​​view plain​​​ ​​copy​​
1. set session transaction isolation level repeatable read;

 

4.设置系统当前隔离级别

 


[sql] ​​view plain​​​ ​​copy​​
1. set global transaction isolation level repeatable read;

 

Read Uncommitted(读取未提交内容)

       在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。
Read Committed(读取提交内容)

       这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。
Repeatable Read(可重读)

       这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读(Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。

Serializable(可串行化) 
       这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。