Mysql:RR隔离级别下的幻读
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql:RR隔离级别下的幻读相关的知识,希望对你有一定的参考价值。
参考技术A 众所周知,mysql在InnoDB下有四种隔离级别:未提交读(Read Uncommitted)
提交后读(Read Committed)
可重复读(Repeatable Read)
串行化(Serializable)
其中可重复读(RR)可以避免脏读( a事务读到b事务回滚前的数据)以及可不重复读( a事务在b事务修改提交的前后,两次分别读到的数据不一致)。但是对于幻读(a事务在b事务insert提交前后,两次分别读到的数据不一致),却存在争议。
下面我们来做一个试验:
对于下面这张简单的数据表
id num
1 11
2 22
3 33
我们开启a、b两个事务
a事务 b事务
begin begin
select * from tb ----
---- insert into tb (id,num)values(4,44)
---- commit
select * from tb ----
commit
试验结果:a事务的两次select查询到的结果相同,在后一次查询中没有返回新插入id=4的那条记录。
据此,很多人判断说RR隔离级别下“不存在”幻读。
但果真如此吗?----
出现上面的试验结果,是因为在RR隔离级别事务下,Mysql会对前一次select的结果快照。所以第二次select其实是快照读(这也正是RR隔离级别下能够避免不可重复读的策略)。
如果我们把试验条件稍作修改,同样开启a、b两个事务:
a事务 b事务
begin begin
select * from tb ----
---- insert into tb (id,num)values(5,55)
---- commit
update tb set num=num+1 ---- #此处a事务做一次修改操作
select * from tb ----
commit
试验结果:在a事务的第二次select中出现了b事务新插入的id=5的记录。
由于做了update操作,之前的快照失效了,所以说RR隔离级别下的快照策略并没能真正避免幻读。
ps. 假如给第二次的select查询上锁(无论是共享锁还是排它锁),也会得到同样的结果,都会令快照失效。
RR隔离级别的查询的幻读场景
以上是关于Mysql:RR隔离级别下的幻读的主要内容,如果未能解决你的问题,请参考以下文章