Skip to Content
面试题库Mysql[面试题] MVCC在RC和RR下的Read View生成时机有何不同?(扩展)

[面试题] MVCC在RC和RR下的Read View生成时机有何不同?(扩展)

版块 A:知识讲解 (Knowledge Recap)

快照读 vs 当前读:

读类型触发方式加锁可见性
快照读普通 SELECT不加锁读历史版本(由 Read View 决定)
当前读SELECT FOR UPDATE / UPDATE / DELETE加锁读最新已提交版本

Read View 可见性判断规则:

  • 版本的 trx_id max_trx_id(比所有活跃事务都晚)→ 不可见
  • min_trx_id ≤ trx_id ≤ max_trx_id → 检查是否在活跃列表中:不在(已提交)→ 可见;在(未提交)→ 不可见

版块 B:面试实战 (Combat Script)

Q:RR 隔离级别真的完全解决幻读了吗?

破局思路:这是一道能把候选人分成两档的题。普通人说”解决了”,高手说”快照读解决了,当前读还需要间隙锁配合”——这个细节才是真正的考察点。

💬 高手逐字稿

关于这个问题,答案是部分解决,不是完全解决,要分两种读的情况来看。

对于快照读(也就是普通的 SELECT),RR 隔离级别下 MVCC 确实解决了幻读。因为事务内的 Read View 在第一次 SELECT 时就固定了,后续不管别的事务插入多少条新数据,我的 Read View 都看不到这些新数据,所以不会出现幻读。

但对于当前读,比如 SELECT ... FOR UPDATEUPDATEDELETE 这类操作,它们读的是最新的已提交版本,而不是历史快照。这时候如果另一个事务插入了新数据并提交,当前读就能看到这条新数据,也就出现了幻读。

这里有一个很多人踩过的坑。 假设事务 A 先用快照读查了某个范围,发现没有数据;然后用 SELECT ... FOR UPDATE 当前读再查一次,这时候如果事务 B 中间插入了数据并提交,事务 A 的当前读就会看到这条数据——这就是幻读。

InnoDB 的解法是:在 RR 级别下,当前读会加间隙锁(Gap Lock),锁住那个查询范围,防止其他事务在这个范围内插入新数据。快照读靠 MVCC,当前读靠 Gap Lock,两者配合才能在 RR 级别下尽可能消除幻读。

最后更新于:
⏱️

登录后开始阅读

当前 MVP 版本只开放邮箱密码登录注册。完成登录后即可进入面试题内容。

还没有账号?先去注册