为什么MYSQL在可重复读隔离级别下会产生幻读?

了解这个问题前需要先重复理解MVCC的工作原理,本文便不多赘述

说幻读是事务A执行两次 select 操作得到不的数据集,即 select 1得到 10 条记录,select 2得到 15 条记录,这其实并不是幻读,既然第一次和第二次读取的不一致,那不还是不可重复读吗,所以这是不可重复读的一种。


正确的理解应该是幻读,并不是说两次读取获取的结果集不同,幻读侧重的方面是某一次的 select 操作得到的结果所表征的数据状态无法支撑后续的业务操作。更为具体一些:select 某记录是否存在,不存在,准备插入此记录,但执行 nsed时发现此记录已存在,无法插入,此时就发生了幻读。

MVCC解决了部分幻读问题,还有其他特殊情况:

发生幻读问题:

1、虽然在可重复读的隔离级别下,READVIEW复用第一次生成的,使得大部分情况下不会出现幻读问题(即前后读取不一致),但是MVCC读取规则是依靠于 READVIEW+UNDOLOG版本链。在下面样例中,使用了update操作执行了当前读,而这个当前读使得UNDOLOG版本链最上面的当前事务ID修改为了A事务的ID。所以在读取规则中当前事务ID=creator_id,所以事务A可以读取到最新的数据版本,从而产生了幻读。

2.执行快照读才会走MVCC机制,保证可重复读。而执行当前读则是利用锁机制读取最新的数据,所以数据前后不一致

而在RR的隔离级别下,使用MVCC+锁机制可以解决幻读问题。锁机制阻塞其他事务的update操作,所以不会产生幻读问题。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值