四种隔离级别按严格程度从低到高依次解决:read uncommitted允许脏读;read committed解决脏读但存在不可重复读;repeatable read(mysql默认)解决脏读和不可重复读,innodb通过mvcc+间隙锁抑制幻读;serializable用读写锁彻底避免三类问题但并发最差。

MySQL 事务隔离级别是面试高频考点,核心在于理解四种级别如何解决脏读、不可重复读、幻读这三类并发问题,以及它们在 InnoDB 中的实现机制(主要是 MVCC + 间隙锁)。
四个隔离级别分别解决什么问题?
按严格程度从低到高排列:
- READ UNCOMMITTED(读未提交):最低级别,允许读取其他事务未提交的数据 → 可能发生脏读
- READ COMMITTED(读已提交):只能读到已提交的数据 → 解决脏读,但同一事务内多次读可能结果不同 → 存在不可重复读
- REPEATABLE READ(可重复读):MySQL 默认级别。保证同一事务中多次读取结果一致 → 解决脏读和不可重复读;但对范围查询(如 SELECT ... WHERE id > 10)仍可能因新插入行而看到不同结果 → 存在幻读(InnoDB 通过间隙锁+Next-Key Lock 在大部分场景下阻止了幻读)
- SERIALIZABLE(串行化):最高级别,强制事务串行执行 → 用读写锁彻底避免脏读、不可重复读、幻读,但并发性能最差
MySQL(InnoDB)怎么实现 REPEATABLE READ?
关键不是“锁住所有数据”,而是结合两种机制:
- MVCC(多版本并发控制):每个事务启动时会创建一个一致性视图(read view),后续查询都基于这个快照,所以不会看到其他事务之后的修改 → 实现非锁定读,解决不可重复读
- 间隙锁(Gap Lock)和 Next-Key Lock(间隙锁+记录锁):在范围条件上加锁,防止其他事务在区间内插入新行 → 抑制幻读(例如 SELECT * FROM t WHERE id
注意:MVCC 只用于普通 SELECT(快照读),而 SELECT ... FOR UPDATE / LOCK IN SHARE MODE 是当前读,会触发锁机制并读最新数据。
常见面试追问点
- RC 和 RR 下,UPDATE 的加锁行为一样吗? 不一样。RC 下只对匹配到的记录加行锁;RR 下还会加间隙锁(尤其范围条件),防止幻插入
- 为什么 MySQL 默认用 RR 而不是 RC? 历史原因 + 主从复制安全(早期基于语句复制 SBR 时,RC 可能导致主从不一致;虽然后来默认改用 ROW 格式,但 RR 仍被保留为默认)
- 幻读到底能不能被 RR 避免? 普通 SELECT 不会(因为 MVCC 快照),但当前读(如带 FOR UPDATE 的 SELECT)+ 间隙锁可以阻挡幻插入;不过若插入后立即 SELECT ... FOR UPDATE,仍可能“看到”新行(因为锁不住未来插入),这时需要业务层或 SERIALIZABLE
怎么查看和设置隔离级别?
查看当前会话级别:
SELECT @@transaction_isolation;设置当前会话隔离级别(重启后失效):
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;全局设置(需 SUPER 权限,影响新连接):
SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;注意:修改全局级别不会影响已存在的连接,只对新建连接生效。










