READ COMMITTED(RC)相比REPEATABLE READ(RR)锁范围更小、释放更快,显著提升高并发写入性能,降低死锁概率与Undo Log压力,但需确认业务是否依赖可重复读语义并配合ROW格式binlog。

RC 级别下锁范围小、释放快,直接减少阻塞
高并发写入场景(如秒杀扣库存、订单状态更新)中,UPDATE 或 DELETE 语句在 READ COMMITTED 下只对实际匹配的行加记录锁(record lock),且语句执行完立即释放;而 REPEATABLE READ 会为整个扫描范围加临键锁(next-key lock),锁持续到事务结束。
- 无索引时,
RC仍可能全表扫描加行锁,但不会升级为间隙锁;RR则大概率触发全范围间隙锁,阻塞后续插入 - 例如:
UPDATE stock SET count = count - 1 WHERE sku_id = 'A001',若sku_id有唯一索引,RC只锁该行;RR还会锁住sku_id对应的间隙,导致插入A002被卡住 -
innodb_row_lock_time_avg在RC下通常压到毫秒级,RR下易升至百毫秒以上,尤其在长事务或范围条件多的业务里
RC 的 MVCC 快照更轻量,降低 Undo Log 压力
READ COMMITTED 每次 SELECT 都生成新 Read View,只依赖语句开始时刻已提交的版本;REPEATABLE READ 复用事务第一次读时的 Read View,要求 Undo Log 保留所有“事务开启前仍在活跃”的旧版本。
- 隐式长事务(如 ORM 自动开启未显式
commit)在RR下极易拖慢purge线程,引发Undo log too large报错 - 写多读少场景(如实时积分更新 + 用户资料页展示),
RC能更快回收历史版本,缓解 buffer pool 压力 - 监控
INFORMATION_SCHEMA.INNODB_METRICS中的history_list_length,RC通常比RR低一个数量级
RC 不默认加间隙锁,死锁概率显著下降
间隙锁(gap lock)是 RR 防幻读的核心机制,也是死锁高发区;RC 默认不使用间隙锁,只在唯一键冲突等极少数场景下才加 Next-Key Lock。
- 典型死锁链:
UPDATE users SET status = 1 WHERE age > 25在RR下锁 (25, ∞),两个事务同时尝试插入 age=30 → X 锁与插入意向锁互斥 -
RC下该语句只锁命中的几行,插入意向锁之间天然兼容,基本规避此类循环等待 - 注意:
INSERT、REPLACE INTO、INSERT ... ON DUPLICATE KEY UPDATE在唯一索引冲突时,RC和RR行为一致,都会加 S 型 Next-Key Lock,此处仍可能死锁
切换 RC 前必须确认业务是否依赖可重复读语义
不是所有业务都能无缝切到 READ COMMITTED。关键看是否存在“先查再判再改”且中间不能被干扰的逻辑闭环。
- 转账类操作:
SELECT balance FROM accounts WHERE id = 123→ 判断余额 ≥ 扣款额 →UPDATE,若两次读之间被其他事务修改,RC下可能超扣 - 分页查询依赖“同事务内结果稳定”:比如后台导出分页列表,
RC下第二页可能漏掉或重复第一条数据 - 验证方式:检查代码中是否有同一事务内多次
SELECT后做条件判断再UPDATE,且未加SELECT ... FOR UPDATE
真正容易被忽略的是:即使切了 RC,若 binlog_format 仍为 STATEMENT,主从间仍可能出现数据不一致——必须配 ROW 格式。


















