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隔离级别下的幻读的主要内容,如果未能解决你的问题,请参考以下文章

MySQL的RR隔离级别与幻读问题

mysql在RR隔离级别下,某些特定场景下出现幻读

MySQL RR和RC隔离级别区别

MySQL RR和RC隔离级别区别

mysql 事物隔离级别rr还是rc好

啥是 MySQL 事务隔离级别?