事务隔离级别
先看一下如何查看事务隔离级别。
# 查看默认事务隔离级别(session) select @@transaction_isolation; # 查看当前会话的隔离级别 select @@session.transaction_isolation; # 查看全局的事务隔离级别 select @@global.transaction_isolation; 复制代码
在 Mysql
下事务的隔离级别有四种,由低到高依次为 Read uncommitted
、Read committed
、Repeatable read
(默认)、Serializable
,这四个级别中的后三个级别可以逐个解决脏读 、不可重复读 、幻读的问题。
1. 脏读
对于两个事务T1与T2,T1读取了已经被T2更新但是还没有提交的字段之后,若此时T2回滚,T1读取的内容就是临时并且无效的。
示例:
打开两个Mysql客户端,分别执行下面操作,查询当前会话的隔离级别(默认 REPEATABLE READ
)。修改当前会话隔离级别为( READ UNCOMMITTED
)。全局事务隔离级别仍然为 REPEATABLE READ
。
mysql> SELECT @@session.transaction_isolation; +-------------------------+ | @@transaction_isolation | +-------------------------+ | REPEATABLE-READ | +-------------------------+ mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; # 修改会话隔离级别 mysql> SELECT @@session.transaction_isolation; # 当前会话隔离级别已修改 +---------------------------------+ | @@session.transaction_isolation | +---------------------------------+ | READ-UNCOMMITTED | +---------------------------------+ mysql> SELECT @@global.transaction_isolation; # 全局事务隔离级别未修改 +--------------------------------+ | @@global.transaction_isolation | +--------------------------------+ | REPEATABLE-READ | +--------------------------------+ 复制代码
之后黑框用来做更新,白框用来查询。
由于黑框的 ④ 回滚,白色背景的客户端中 ③ 读取的数据就是临时并且无效的。即脏读。
2. 不可重复读
对于两个事务T1和T2,T1读取了一个字段,然后T2更新了该字段并提交之后,当T1再次读取的时候,结果不一致的情况发生。
由于黑框的更新操作,白框出现两次读取的结果不一致。
3. 幻读
对于两个事务T1、T2,T1从表中读取数据,然后T2进行了INSERT操作并提交,当T1再次读取的时候,结果不一致的情况发生。
由于黑框的插入操作,白框出现两次读取的结果不一致。
几种现象在各隔离级别中出现的可能性:
隔离级别 | 脏读(Dirty Read) | 不可重复读(NonRepeatable Read) | 幻读(Phantom Read) |
未提交读(Read uncommitted) | 可能 | 可能 | 可能 |
已提交读(Read committed) | 不可能 | 可能 | 可能 |
可重复读(Repeatable read) | 不可能 | 不可能 | 可能 |
可串行化(Serializable ) | 不可能 | 不可能 | 不可能 |