mysql的innodb RR隔离级别能解决幻读吗

mysql的innodb RR隔离级别能解决幻读吗

先说结论:能解决,但不能完全解决。

在RR和RC级别下,数据库的读分为快照读和当前读:
快照读:又叫一致性非锁定读,单纯的select操作,不会进行加锁。通过mvcc通知数据的一致性,读取的是快照(ReadView)中的数据,可能是历史数据
当前读:又叫一致性锁定读,select … for update/in share mode、update、insert、delete。执行操作时会加上X|S锁(共享锁和排它锁),读取的总是当前的最新数据

对于快照读,是通过mvcc来解决事务中的脏读、不可重复读以及幻读问题的。
实际上不管是RR还是RC,读取数据时根据undolog数据链的事务id和ReadView中各个参数(当前活跃的事务id集合,下一个未分配的事务id,活跃事务id中最小的事务id)对比的规则都是同一套,只是二者ReadView生成的时机不同。
对于RR隔离级别,ReadView是在事务读开始时候产生,在事务结束之前都是用这一个readView,因此无论怎么变化,看到的东西都不会变化。从而解决了脏读、不可重复读以及幻读问题。
对于RC隔离级别,每次读取的时候都会产生一个readView,因此无法解决不可重复读以及幻读问题。
因此:RR隔离级别下,快照读是可以解决脏读、不可重复读以及幻读问题的。

对于当前读,是通过锁(记录锁,间隙锁等)来解决脏读、不可重复读以及幻读问题的,你读取的行,以及行的间隙都会被加锁,直到事务提交时才会释放,其他的事务无法进行修改,所以也不会出现不可重复读、幻读的情形。而间隙锁在RR隔离级别中才生效。
因此:RR隔离级别下,当前读也是可以解决脏读、不可重复读以及幻读问题的。

那幻读是怎么产生的呢?为什么说RR隔离级别下没有完全解决幻读问题。
其实在RR级别下,有下面两种情况是可以产生幻读情况的。
1、事务1 先快照读,事务2新增了一条数据并提交事务,事务1再当前读。
2、事务1 先快照读,事务2新增了一条数据并提交事务,事务1对事务2提交的数据进行了修改,事务1再次快照读。

情况1不用说了吧,很好理解。对于情况2, 事务1的更新操作不属于快照读,因此事务1的更新操作是可以生效的,而当前数据会记录最新修改的记录,最新修改的记录为当前事务自己,所以是能看到的。

  • 12
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值