首页/数据/数据库速查/RC 与 RR 的锁行为差异与选型
性能与调优57 条

RC 与 RR 的锁行为差异与选型

READ COMMITTED 与 REPEATABLE READ 的核心差异在间隙锁:RC 基本不用 gap lock(减少锁冲突),RR(默认)用临键锁防幻读;互联网 OLTP 常用 RC。

数据库速查数据更新于 2026-10-13

隔离级别与锁范围

READ COMMITTED 与 REPEATABLE READ 最实质的差别落在间隙锁上。RR 是 InnoDB 的默认级别,范围条件会加临键锁(记录锁加间隙锁)以阻止幻读;RC 基本不用间隙锁,只锁匹配到的记录,锁冲突更少,代价是可能出现幻读。互联网 OLTP 场景多用 RC 换取更低的锁等待,代价是业务要自己处理读-改-写竞态。

基本信息

适用平台MySQL 5.7 / 8.0 的 InnoDB
默认级别REPEATABLE READ
切换语句SET GLOBAL transaction_isolation = 'READ-COMMITTED'
生效范围全局设置只影响新建立的连接
前提条件binlog_format 需为 ROW 才能安全使用 RC

典型使用场景

  • 高并发写入场景锁等待明显,评估从 RR 切到 RC
  • 批量更新出现大量临键锁冲突,需要缩小锁范围
  • 排查「明明只更新几行却锁住一片」的现象
  • 适配从其他数据库(如 Oracle,默认 RC)迁移过来的业务
  • 评估切换风险:梳理依赖可重复读语义的批次逻辑

查看与切换

查看与切换
-- 查看当前会话与全局的隔离级别
SELECT @@transaction_isolation;
SELECT @@global.transaction_isolation;
-- 会话级切换(只影响当前连接,适合验证)
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- 全局切换:只影响之后新建的连接
SET GLOBAL transaction_isolation = 'READ-COMMITTED';
-- 切换前确认二进制日志格式
SHOW VARIABLES LIKE 'binlog_format';

RC 与 RR 行为对比

行为RCRR
间隙锁基本不使用范围条件下大量使用
幻读可能出现由临键锁防住
相同行的多次读每次读最新已提交版本同一事务内结果保持一致
锁冲突与死锁概率较低较高
读-改-写竞态需显式加锁处理由重复读语义隐式缓解
RC 下每条语句读取的是最新已提交版本,同一事务内两次相同查询可能得到不同结果;依赖一致性快照做批次计算的逻辑要重新验证。
切换隔离级别是全局行为变更:先在会话级验证业务表现,再选择低峰时段切换全局,并准备好回切方案。

易错点

  • 从 RR 切到 RC 却不评估业务:依赖可重复读的统计与批次逻辑出现数据漂移,问题往往在月底结算时才暴露
  • 以为 RC 完全没有间隙锁:外键约束检查、唯一键冲突等场景仍会产生间隙锁,锁等待不会归零
  • 在 RC 下仍用不加锁的读-改-写:并发下出现丢失更新,必须显式 SELECT ... FOR UPDATE 或使用原子更新语句
  • 全局切换后未验证已有连接:老连接仍保持原级别,出现「有的会话行为不同」的诡异现象

数据来源与参考

  • MySQL 8.0 Reference Manual: Transaction Isolation Levels
  • MySQL 8.0 Reference Manual: InnoDB Locking

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌