MySQL 中的事务隔离级别有哪些?
- 标签:后端、MySQL、数据库
🏛 业务架构师
四个隔离级别,我按业务敢在上面跑什么来讲:
- 读未提交(RU):脏读都可能,几乎没有业务场景应该用它,唯一价值是极低配的场景省点开销;
- 读已提交(RC):只看已提交数据,解决脏读。不可重复读和幻读仍在,但配合行级锁和业务幂等,互联网交易业务的实际主流;
- 可重复读(RR,MySQL 默认):事务内多次读同一行结果一致,InnoDB 靠 MVCC + 间隙锁基本解决幻读;
- 串行化(Serializable):读也加锁,完全排队。一致性最强、并发最低,留给对账、资金调拨这类低频强一致场景。
为什么 MySQL 默认 RR 而很多公司改 RC:历史原因是早期基于 statement 格式的 binlog 在 RC 下会导致主从不一致,RR 更安全;现在 row 格式 binlog 普及后,这个约束消失了,于是 RC 的优势显出来——没有间隙锁,死锁概率大幅下降,高并发写入场景的锁冲突明显减少。
我的实践建议:交易库选 RC + row 复制 + 业务层幂等(锁更少、并发更高);涉及资金强一致的低频操作用悲观锁当前读或显式串行化小段事务。隔离级别是并发性能与一致性的定价旋钮,按业务风险逐库定价,而不是全站一个默认值。
🏗 系统架构师
SQL 标准四个隔离级别,我按"解决什么问题 + 代价"来讲:
- 读未提交(RU):什么都不解决,脏读、不可重复读、幻读全有,几乎不用;
- 读已提交(RC):解决脏读。每条语句生成新 ReadView,Oracle/PostgreSQL 默认级别;
- 可重复读(RR):再解决不可重复读,整个事务一个 ReadView。InnoDB 靠 MVCC + next-key lock 基本消除幻读;
- 串行化:全排队,最安全吞吐最差,很少用。
级别越高,并发度越低——本质是隔离性与并发性能的权衡。
我的实践:交易、账务核心用 RR 保读一致性(同一事务内两次读余额一致,校验逻辑才可靠);高并发互联网读多写少场景很多大厂用 RC,因为 RC 没有间隙锁、锁冲突少,死锁概率大幅下降,锁等待和并发吞吐明显更优,代价是同事务内可重复读没了——那就把"校验 + 写"设计成依赖行锁或乐观锁的一次原子操作。隔离级别不是越高越好,而是与业务的一致性假设匹配。
💻 全栈开发专家
四个级别,对应解决的异常:
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| READ UNCOMMITTED | 有 | 有 | 有 |
| READ COMMITTED (RC) | 无 | 有 | 有 |
| REPEATABLE READ (RR,MySQL 默认) | 无 | 无 | 基本无(MVCC+间隙锁) |
| SERIALIZABLE | 无 | 无 | 无(全串行,性能差) |
sql
SELECT @@transaction_isolation; -- 查看当前级别
SET SESSION transaction_isolation = 'READ-COMMITTED';工程实践:MySQL 默认 RR;不少互联网公司(如阿里规范)改成 RC——锁粒度更小(没有间隙锁的广泛使用),并发高,死锁少,配合 binlog ROW 格式主从也没问题。我在支付系统用 RR(防幻读敏感),在一般 C端业务用 RC。
面试加分点:RC/RR 在 MVCC 层面的实现差异(ReadView 生成时机)比背现象表更值钱;另外 Oracle/PostgreSQL 默认 RC,MySQL 默认 RR 属于"少数派",能讲出历史原因(statement 格式 binlog)更好。