MYSQL分析案例

假设数据库隔离级别为 RR,事务 A 先执行普通SELECT * FROM user WHERE id < 5(快照读),此时事务 B 插入 id=3 的行并提交,事务 A 再次执行相同的普通 SELECT,能看到 id=3 的行吗?为什么?

完整解析

结论:事务 A看不到 id=3 的行。
核心原因(结合 RR 级别 ReadView 规则):
  1. RR 级别 ReadView 的生成规则 :事务 A 第一次执行普通 SELECT(快照读)时,会生成一个固定的 ReadView ,这个 ReadView 包含了 "生成瞬间的活跃事务 ID 列表、min_trx_id、max_trx_id" 等关键信息,且在事务 A 提交前不会更新、不会重建
  2. 数据可见性判断
    • 事务 B 是在事务 A 生成 ReadView 之后开启并提交的,因此事务 B 的事务 ID ≥ ReadView 的max_trx_id(高水位线);
    • 根据 ReadView 的可见性规则:数据行的修改事务 ID ≥ max_trx_id时,该数据对当前事务不可见
    • 即使事务 B 提交了 id=3 的行,事务 A 的快照读仍会复用最初的 ReadView,因此无法看到这个新插入的行。

再来分析第二种情况(在第一问的情况下)

若事务 A 后续执行UPDATE user SET name = 'test' WHERE id < 5(当前读),能修改到事务 B 插入的 id=3 的行吗?这个过程中会触发什么锁机制?

1. 为什么能修改到 id=3 的行?(当前读 vs 快照读的本质区别)
  • 快照读(普通 SELECT)依赖 ReadView 读取历史版本,而当前读(UPDATE/DELETE/SELECT ... FOR UPDATE)不依赖 ReadView,会直接读取数据的最新版本;
  • 事务 B 已经提交了 id=3 的行,该行是数据库中的 "最新数据",因此事务 A 执行 UPDATE(当前读)时,会扫描到这个最新的 id=3 的行,并执行修改操作;
  • 这也是 RR 级别下 "极特殊幻读场景" 的体现:快照读看不到,但当前读能修改到,看似 "矛盾",实则是两种读取方式的机制不同。
2. 触发的锁机制(Next-Key Lock):

事务 A 执行UPDATE user SET name = 'test' WHERE id < 5时,InnoDB 会先执行 "当前读扫描",再加锁,过程如下:

  1. 第一步:扫描最新数据:遍历 id < 5 的所有行(包括事务 B 插入的 id=3 的行);
  2. 第二步:加记录锁 :给 id=3 的行加记录锁,防止其他事务同时修改 / 删除这行;
  3. 第三步:加间隙锁 :给 id <5 的间隙(如 (0,3)、(3,5))加间隙锁,防止其他事务在这个范围内插入新行;
  4. 最终触发的是Next-Key Lock(记录锁 + 间隙锁),而非单独的间隙锁或记录锁。
相关推荐
宇擎智脑科技2 小时前
RAG系统数据库架构选型对比:SurrealDB单体方案 vs 多数据库组合方案深度分析
数据库·人工智能·数据库架构
饮长安千年月2 小时前
Linux下的敏感目录
linux·网络·数据库·web安全
web182854825123 小时前
代码诊疗室:破解疑难Bug实战
数据库
数据知道4 小时前
MongoDB 数据库与集合管理:显式创建与隐式创建的区别及生产环境建议
数据库·mongodb·oracle
数据知道4 小时前
MongoDB 的 CRUD 极速上手:insertOne/insertMany 与批量写入的性能差异
数据库·mongodb
愚公搬代码4 小时前
【愚公系列】《数据可视化分析与实践》019-数据集(自定义SQL数据集)
数据库·sql·信息可视化
甲枫叶4 小时前
【claude产品经理系列11】实现后端接口——数据在背后如何流动
java·数据库·人工智能·产品经理·ai编程·visual studio code
甲枫叶4 小时前
【claude产品经理系列12】接入数据库——让数据永久保存
java·数据库·人工智能·产品经理·ai编程
Elastic 中国社区官方博客4 小时前
Elasticsearch:通过最小分数确保语义精度
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索