RC和RR隔离级别下MVCC的差异?

读已提交(RC)和可重复读(RR)是 InnoDB 中基于 MVCC 实现的两个核心隔离级别,二者的核心差异在于 Read View 的生成时机,这直接导致了快照读的一致性、版本可见性判断的不同。

我们从核心差异点、行为对比、实例验证三个维度拆解,结合之前的版本链、Read View 知识,帮你彻底理清。

一、核心差异:Read View 的生成时机

这是 RC 和 RR 隔离级别下 MVCC 行为差异的根源,没有之一。

隔离级别 Read View 生成时机 核心影响
读已提交(RC) 每次执行快照读(普通 SELECT)时,都生成一个新的 Read View 每次读都会基于最新的活跃事务列表判断版本可见性,能看到其他事务刚提交的版本
可重复读(RR) 事务中第一次执行快照读时生成 Read View,后续所有快照读复用这个 Read View 整个事务内用同一个判断规则,多次读同一数据结果一致,不会看到其他事务提交的版本

补充:当前读(SELECT ... FOR UPDATE/INSERT/UPDATE)在两个隔离级别下行为完全一致------ 都是读取最新版本并加锁,不依赖 Read View 快照。

二、关键行为差异对比

基于 Read View 生成时机的不同,RC 和 RR 在 MVCC 层面会表现出 3 个核心差异,这也是面试高频考点:

对比维度 读已提交(RC) 可重复读(RR)
快照一致性 不保证可重复读:同一事务内多次快照读同一数据,结果可能不同 保证可重复读:同一事务内多次快照读,结果完全一致
版本可见性 能看到其他事务在两次快照读之间提交的新版本 看不到其他事务在本事务执行期间提交的任何版本
幻读问题 存在幻读:两次 SELECT 可能返回不同数量的行 解决幻读:InnoDB 通过 Next-Key Lock (行锁 + 间隙锁)配合 MVCC,避免幻读
Undo Log 清理 清理更及时:因为每次读都用新 Read View,旧版本很快不再被引用 清理较慢:因为事务复用 Read View,旧版本可能被长时间引用

三、实例验证:同一个场景下 RC 和 RR 的不同表现

用一个经典并发场景,直观对比两者差异。前置条件:

  • user 表 id=1 的数据版本链:当前版本(102:王五) → 历史版本1(101:李四) → 历史版本2(0:张三)
  • 事务 102 未提交时,开启事务 103 执行快照读。

场景流程

时间 事务 102(未提交) 事务 103(隔离级别 RC) 事务 103(隔离级别 RR)
T1 UPDATE user SET name='王五' WHERE id=1;(未提交) 开始事务 开始事务
T2 - SELECT name FROM user WHERE id=1;(快照读) SELECT name FROM user WHERE id=1;(快照读)
T3 提交事务 - -
T4 - SELECT name FROM user WHERE id=1;(快照读) SELECT name FROM user WHERE id=1;(快照读)

结果分析

  1. T2 时刻(事务 102 未提交)

    • 无论 RC/RR,生成的 Read View 中 m_ids 都包含 102(活跃事务)。
    • 判断当前版本(102: 王五):DB_TRX_ID=102 在 m_ids 中 → 不可见。
    • 遍历版本链,找到历史版本 1(101: 李四):DB_TRX_ID=101 < min_trx_id → 可见。
    • RC/RR 结果一致 :返回 李四。
  2. T4 时刻(事务 102 已提交)

    • RC 隔离级别 :第二次 SELECT 会生成新的 Read View ,此时 m_ids 已不包含 102(事务 102 已提交)。判断当前版本(102: 王五):DB_TRX_ID=102 不在 m_ids 中 → 可见。结果 :返回 王五(两次读结果不同,不保证可重复读)。
    • RR 隔离级别 :第二次 SELECT 复用 T2 生成的 Read View ,m_ids 仍包含 102。判断当前版本(102: 王五):DB_TRX_ID=102 在 m_ids 中 → 不可见。继续遍历版本链,返回 李四(两次读结果相同,保证可重复读)。

四、总结:RC 和 RR 的 MVCC 差异本质

本质 读已提交(RC) 可重复读(RR)
核心区别 每次快照读刷新 Read View 事务内复用 Read View
一致性 语句级一致性(每次读独立) 事务级一致性(全程一致)
适用场景 对一致性要求低、追求高并发的业务(如电商商品列表) 对一致性要求高的业务(如金融转账、订单支付)
相关推荐
红海云27 分钟前
Jev:给智能系统做判断的模型
大数据·数据库·人工智能
wjkjpcba32 分钟前
PCBA烧录程序是什么:PCBA包工包料厂家解析烧录与测试
linux·数据库·人工智能·smt贴片加工·pcba贴片加工厂
꯭自꯭闭꯭1 小时前
达梦事物特性及MVCC
linux·运维·数据库
小马同学-1 小时前
MySQL主从复制和读写分离
数据库·mysql
谢亮_vipxieliang1 小时前
Spring 事务失效的常见场景
java·开发语言·数据库·spring boot
海绵宝宝转agent2 小时前
MySql高频面试八股开源笔记总结
mysql·面试·开源
geovindu2 小时前
sql: JSON and XML Data Handling in SQL using sql server 2025
大数据·数据库·sqlserver·数据库开发·数据库架构
IT大白鼠3 小时前
图数据库系列 · 第 02 篇——架构拆解:原生图存储到因果集群
数据库·架构·nosql
余槐i3 小时前
数据没回滚也不报错:@Transactional 自调用失效的 3 种复现与修复
spring boot·mysql·多线程·spring 事务
EatFan3 小时前
从“框架混战“到“运行时收敛“:2026 年 AI Agent 开发框架的三条路线之争
java·数据库·人工智能·多智能体·ai agent·mcp·agent 框架