订阅更新

同一个事务里先更新再查询,查到的是旧数据——事务隔离级别到底怎么回事?

MySQL手册 第 6 题 约 3 分钟读完

本文目录
  1. 先说结论
  2. 业务场景:账户余额“看不到”最新变化
  3. 四个隔离级别详解
  4. MVCC是怎么实现的?(简单说)
  5. 面试高频追问:RC和RR生产环境怎么选?
  6. 总结

先说结论

MySQL InnoDB默认的隔离级别是Repeatable Read(可重复读)。它通过MVCC(多版本并发控制)实现:每个事务看到的是事务开始时的“快照”,即使其他事务已经提交了修改,你也看不到。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

事务隔离级别是MySQL面试的必考题,但很多人只能背出四个级别的名字和定义。面试官真正想听的是“你在生产环境遇到过什么因为隔离级别导致的问题”。今天用一个真实的场景来讲透。

业务场景:账户余额“看不到”最新变化

我在元宇宙社交App遇到过一个问题:用户充值后查余额,显示的还是老余额。原因是业务代码在一个大事务里先做了很多操作,最后才查余额。由于RR级别下读的是事务开始时的快照,充值操作在另一个事务里已经提交了,但当前事务看不到。

四个隔离级别详解

级别脏读不可重复读幻读性能
Read Uncommitted✔有✔有✔有最高(没人用)
Read Committed✖解决✔有✔有高(Oracle默认)
Repeatable Read✖解决✖解决✖InnoDB解决中(MySQL默认)
Serializable✖解决✖解决✖解决最低(没人用)

注意:MySQL的RR级别通过Next-Key Lock解决了幻读问题,这是MySQL特有的,其他数据库的RR级别通常不能解决幻读。这个细节在面试里主动提一下,非常加分。

MVCC是怎么实现的?(简单说)

每行数据都有一个隐藏的“版本链”(undo log)。当你在事务里做SELECT时,MySQL会根据你的事务ID和这个版本链,找到你应该看到的版本。

类比:就像你在早上9点进入了一个“时间胶囊”,无论外面怎么变,你看到的都是9点时的世界。直到你离开胶囊(提交事务)才能看到新变化。

面试高频追问:RC和RR生产环境怎么选?

MySQL默认RR,但很多互联网公司会改成RC。原因:

RR的问题: 长事务会导致undo log堆积,占用大量存储空间。而且RR下的锁范围更大(Next-Key Lock),死锁概率更高。

RC的优势: 锁范围更小、undo log回收更快、并发性能更好。但要注意不可重复读的问题。

我待过的公司,元宇宙社交App用的是默认的RR,出海硬件公司用的是RC。选择的依据是业务复杂度和并发量。

总结

记住两个核心:MySQL默认RR + MVCC快照读。RR下读的是事务开始时的快照,RC下读的是每条SQL执行时的最新快照。面试时能结合一个真实场景说清楚“遇到过什么问题、怎么解决的”,就很稳。

下一篇聊一个每个后端都应该掌握的场景:为什么要用B+树而不是Hash索引?什么场景用Hash索引更好?

你们生产环境用的哪个隔离级别?评论区聊聊~

关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长

刷题进度保存在当前浏览器