真实面经题目 · 原创解析

MySQL 事务隔离级别有哪些?

这题考察对 SQL 标准隔离级别和 MySQL InnoDB 实现差异的理解。面试中不能只背四个名字,还要说明每个级别解决哪些并发读问题、MySQL 默认为什么是可重复读,以及 InnoDB 通过 MVCC、快照读、当前读和 next-key lock 在不同读场景下处理一致性与幻读的边界。

出现于:阿里巴巴 · 后端开发

60 秒回答模板

MySQL 事务隔离级别按从低到高可以分为读未提交、读已提交、可重复读和串行化。读未提交允许读到其他事务尚未提交的数据,可能出现脏读、不可重复读和幻读,实际业务中很少使用。读已提交只能读到已提交数据,解决脏读,但同一事务内两次读取可能看到其他事务新提交的结果,所以仍可能不可重复读和幻读。可重复读是 InnoDB 的默认隔离级别,普通快照读会基于第一次一致性读创建的 Read View 保持同一事务内读结果稳定,解决不可重复读;对当前读场景,InnoDB 会结合记录锁、间隙锁和 next-key lock 限制范围内插入,从而在很多加锁读和更新场景下抑制幻读。串行化隔离级别最强,会让事务近似串行执行,一致性最好但并发能力最低。回答时要强调:SQL 标准里的幻读概念和 InnoDB RR 的实现效果不能简单等同,快照读与当前读的机制不同,是否会遇到幻读要结合具体 SQL 类型、索引条件和加锁方式判断。

考点 四种隔离级别的基本定义
主线 三类典型并发读问题
易错点 只背四个隔离级别名称,却说不清每一级能避免哪些并发读问…

深入解析

01

四种隔离级别的基本定义

MySQL 支持的事务隔离级别包括读未提交、读已提交、可重复读和串行化。隔离级别本质上是在并发性能和一致性之间做权衡:级别越低,事务之间可见性越宽松,并发性能通常越高,但异常读风险越大;级别越高,系统对读写冲突的约束越强,一致性更容易保证,但锁等待、死锁概率和吞吐损耗也会增加。面试中先给出四个级别,再按它们解决的问题逐层展开,结构会更清晰。

02

三类典型并发读问题

脏读是指一个事务读到了另一个事务尚未提交的数据,如果对方回滚,前一个事务就基于不存在的数据做了判断。不可重复读是指同一事务内按相同条件读取同一行数据,两次结果不一致,通常由其他事务提交了修改导致。幻读更强调范围查询的结果集合变化,例如第一次查某个范围有 10 行,另一个事务插入满足条件的新行并提交后,再查变成 11 行。三者都和可见性有关,但关注点不同,不能混成一个概念。

03

读未提交与读已提交

读未提交是最低隔离级别,它允许读取其他事务未提交的修改,因此脏读、不可重复读、幻读都有可能发生。读已提交比它更常用,规则是每次读取只能看到已经提交的数据,所以脏读被消除;但它通常是语句级一致性,同一事务中不同语句可能创建不同的可见性视图,因此前一次查询看不到的提交,后一次查询可能看得到。很多数据库默认使用读已提交,但 MySQL InnoDB 默认不是这个级别。

04

可重复读与 InnoDB 默认级别

InnoDB 的默认隔离级别是可重复读,这是 MySQL 面试中经常追问的点。可重复读的目标是让同一事务内多次读取同一批数据时结果保持一致。InnoDB 普通一致性读依赖 MVCC 和 Read View:事务第一次执行快照读时确定可见版本,后续快照读沿用这个视图,因此即使其他事务提交了修改,当前事务仍然读到符合自己快照的数据版本。这解释了为什么可重复读能在普通读场景下避免不可重复读。

05

MVCC、快照读与当前读

MVCC 是多版本并发控制,核心是同一行数据可以保留多个历史版本,读操作通过事务版本信息判断哪个版本可见,从而减少读写互相阻塞。普通 select 通常是快照读,它读的是某个时间点的一致性版本,不主动加锁。当前读则读取最新已提交并且需要参与加锁判断的数据,例如加锁查询、更新、删除、插入相关检查等。当前读不能只靠历史版本解决并发写入问题,所以会引入记录锁、间隙锁或 next-key lock 来约束其他事务。

06

幻读与 next-key lock 的边界

在 SQL 标准语义中,可重复读仍可能出现幻读,串行化才彻底禁止这类现象。但 InnoDB 的可重复读实现更复杂:普通快照读由于使用同一个 Read View,通常不会看到后续插入的新行;当前读如果命中合适索引并进行范围加锁,next-key lock 会锁住记录及其前后的间隙,阻止其他事务在范围内插入,从而抑制幻读。边界在于它依赖具体 SQL、索引、锁模式和访问路径;如果条件没有合适索引、使用不当的普通读,或不同语句混合快照读与当前读,现象就不能简单用一句“完全解决幻读”概括。

07

串行化的代价与适用场景

串行化是最高隔离级别,它要求事务执行效果等价于一个个串行执行,理论上可以避免脏读、不可重复读和幻读。代价是并发性能显著下降,读写之间更容易互相阻塞,锁等待时间和系统吞吐压力都会上升。因此在互联网业务和常见后台系统中,串行化通常不是默认选择,更多用于一致性要求极高、并发规模有限、业务能接受性能损耗的场景。面试回答中要体现这种工程取舍。

易错点

  • 只背四个隔离级别名称,却说不清每一级能避免哪些并发读问题。
  • 把 MySQL InnoDB 默认级别答成读已提交,混淆了不同数据库的默认行为。
  • 把不可重复读和幻读混为一谈,没有区分同一行变化和范围结果变化。
  • 简单声称可重复读完全解决幻读,忽略快照读、当前读、索引和锁模式的边界。
  • 认为 MVCC 可以解决所有并发问题,忽略当前读仍然需要记录锁、间隙锁和 next-key lock。

面试官追问

MySQL InnoDB 默认隔离级别是什么?为什么常被问?

InnoDB 默认隔离级别是可重复读。它常被问是因为很多数据库默认是读已提交,候选人容易混淆。面试官还会借此继续追问 MVCC、Read View、快照读、当前读以及 InnoDB 如何在可重复读下处理幻读。

读已提交和可重复读在 MVCC 上有什么差异?

读已提交通常每条语句生成新的可见性视图,所以同一事务内后续查询可能看到其他事务刚提交的数据。可重复读则通常在事务第一次快照读时确定 Read View,后续快照读复用它,因此同一事务中读取结果更稳定。

InnoDB 的可重复读是否完全解决幻读?

不能简单说完全解决。普通快照读因为使用一致性 Read View,通常不会看到后续插入的新行;当前读在合适索引和范围加锁下,会通过 next-key lock 阻止范围内插入。但不同 SQL、索引和锁模式会影响结果。

快照读和当前读分别指什么?

快照读读取的是事务可见的历史版本,普通 select 通常属于这种读,不主动等待最新写锁。当前读读取最新可用数据并参与加锁判断,例如 select for update、update、delete 等,它需要通过锁来保证后续修改的正确性。

为什么串行化隔离级别不常作为默认选择?

串行化一致性最强,但会显著降低并发能力,让读写冲突更频繁地变成等待,事务越长影响越明显。大多数业务更愿意使用可重复读或读已提交,再配合索引、事务设计和必要的显式锁控制一致性。