Mysql是否解决了RR隔离级别下的幻读问题?

Mysql不同隔离级别下的数据查询问题,如脏读、幻读等是Java开发人员必须掌握的知识之一,网上的信息来源驳杂,但RR级别下的幻读问题基本上的描述都是Mysql InnoDB引擎通过 MVCC + 间隙锁 的方式解决了,但是真的是这样吗?

Mysql版本 8.0.33

image

会话隔离级别

image

快照读、当前读

快照读:读取的是快照版本。普通的SELECT就是快照读。通过mvcc来进行并发控制的,不用加锁。

当前读:读取的是最新版本。UPDATE、DELETE、INSERT、SELECT … LOCK IN SHARE MODE、SELECT … FOR UPDATE是当前读。

演示流程

image

  1. balance表中有4条数据
    image
  2. 事务B执行并提交后,第3步中的查询仍保持第一步中的结果,因为MVCC在RR级别下,只在开启事务时生成一个Read View,所以快照读在一次事务中保持相同的结果
    image
  3. 但是当前读结果中出现了事务B新增的数据,因为当前读锁定整个表,所以快照失效
    image
  4. 并且如果在事务B提交之前,在事务A中进行select for update,查询会被阻塞,这是因为间隙锁锁定了数据间隙,而当前读也要加锁,所以导致当前读在阻塞等待获取锁;这时如果commit掉事务B,那么事务A的select语句会立即查询出结果
    image

所以在RR级别下还是有可能发生幻读的

posted @ 2025-04-10 13:22  卡利的亲爹  阅读(23)  评论(0)    收藏  举报