MySQL那种事务隔离级别性能高
# 四种隔离级别性能排序
| 隔离级别 | 性能排序 | 原因 | |
|---|---|---|---|
| 读未提交 | READ UNCOMMITTED | ⭐⭐⭐⭐⭐ 最高 | 几乎不加锁,但会读到脏数据,业务上几乎无法使用 |
| 读已提交 | READ COMMITTED | ⭐⭐⭐⭐ 高 | 只加行锁(且是写锁),读操作不加锁,并发性好 |
| 可重复读 | REPEATABLE READ | ⭐⭐⭐ 中等 | 要维护 MVCC 快照,且 InnoDB 默认级别,有间隙锁(Gap Lock)开销 |
| 串行化 | SERIALIZABLE | ⭐ 最低 | 所有操作串行化,读也加锁,并发度最低 |
隔离级别越严格,性能越差,数据一致性越好。
性能最高的是 READ UNCOMMITTED(读未提交),但实际生产中几乎不用。 最常用、最推荐的是 READ COMMITTED(读已提交)。
# 为什么 READ COMMITTED 性能优于 REPEATABLE READ?
这是生产环境中最常见的两种隔离级别,我详细展开:
| 差异点 | READ COMMITTED | REPEATABLE READ |
|---|---|---|
| 快照生成时机 | 每条 SQL 执行前生成新快照 | 事务开始时生成快照,整个事务共用 |
| 间隙锁(Gap Lock) | 无间隙锁,锁范围小 | 有间隙锁,锁范围大,容易阻塞 |
| 锁竞争 | 锁竞争少,并发度高 | 间隙锁可能导致更多的锁等待和死锁 |
| 主从复制 | 有主从切换风险 | 基于 GTID 的复制更安全(不绝对) |
-- 举个例子说明间隙锁的影响
-- 表:users (id PRIMARY KEY, status)
-- 数据:id = 1, 3, 5, 7, 9
-- 在 REPEATABLE READ 下
BEGIN;
SELECT * FROM users WHERE id BETWEEN 3 AND 7 FOR UPDATE;
-- 会锁住 id = 3, 4, 5, 6, 7 (间隙 4、6 也被锁)
-- 其他事务想插入 id=4 会被阻塞 ❌
-- 在 READ COMMITTED 下
BEGIN;
SELECT * FROM users WHERE id BETWEEN 3 AND 7 FOR UPDATE;
-- 只锁住 id = 3, 5, 7 (记录锁)
-- 其他事务想插入 id=4 可以成功 ✅
# 怎么选?—— 一个决策矩阵
| 业务场景 | 推荐隔离级别 | 原因 |
|---|---|---|
| 互联网金融、支付、账务 | READ COMMITTED | 高并发,不强求可重复读,性能优先,防幻读由业务代码兜底 |
| OLTP 报表、对账 | READ COMMITTED 或 REPEATABLE READ | 对账类建议加锁语句明确顺序,读已提交即可 |
| 需要事务内多次读取一致(如库存扣减) | REPEATABLE READ(但建议上锁) | 其实推荐用 SELECT FOR UPDATE + READ COMMITTED 组合 |
| 需要严格防幻读,业务无法重试 | REPEATABLE READ | 对 MySQL 内部逻辑依赖较高,建议优先用分布式锁或业务幂等 |
| 批处理、ETL 导入 | READ UNCOMMITTED 或 READ COMMITTED | 可接受脏读,性能优先 |
| 金融强一致性要求 | SERIALIZABLE(不推荐) | 不建议用这个级别,建议用应用层分布式事务 |
从阿里巴巴《Java 开发手册》到各大公司的 MySQL 规范,READ COMMITTED 已经成为主流选项:
- MySQL 默认是 REPEATABLE READ,但你完全可以根据业务需求调整为 READ COMMITTED,这不是“异端”。
- 互联网公司的数据库基本都会改成 READ COMMITTED,因为它能更好地适应高并发场景。
- 阿里巴巴内部规定:交易、支付、订单等核心系统强制使用 READ COMMITTED。
原因很简单:互联网业务的特点是“读多写少、数据终态可修复”,而不是“强一致事务块”。 把一致性的部分交给业务代码(如幂等、乐观锁、分布式锁),让数据库专注于“快”。
# 总结一句话
性能上 READ UNCOMMITTED 最高,但生产环境几乎不用。
互联网业务首选 READ COMMITTED:高并发、低锁冲突、可配合业务幂等与重试。
金融核心账务/报表/对账也选 READ COMMITTED,但加锁语句要写清楚顺序,避免死锁。
上次更新: 2026-06-25 17:18:05