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(记录锁 + 间隙锁),而非单独的间隙锁或记录锁。
相关推荐
Shely201723 分钟前
MySQL数据表管理
数据库·mysql
爬山算法30 分钟前
MongoDB(80)如何在MongoDB中使用多文档事务?
数据库·python·mongodb
APguantou37 分钟前
NCRE-三级数据库技术-第2章-需求分析
数据库·需求分析
寂夜了无痕1 小时前
MySQL 主从延迟全链路根因诊断与破局法则
数据库·mysql·mysql主从延迟
爱丽_1 小时前
分页为什么越翻越慢:offset 陷阱、seek 分页与索引排序优化
数据库·mysql
APguantou1 小时前
NCRE-三级数据库技术-第12章-备份与数据库恢复
数据库·sqlserver
Bat U1 小时前
MySQL数据库|表设计+新增+分组查询
数据库·mysql
麦聪聊数据2 小时前
企业数据流通与敏捷API交付实战(五):异构数据跨库联邦与零代码发布
数据库·sql·低代码·restful
Elastic 中国社区官方博客2 小时前
当 TSDS 遇到 ILM:设计不会拒绝延迟数据的时间序列数据流
大数据·运维·数据库·elasticsearch·搜索引擎·logstash
qing222222222 小时前
Linux中修改mysql数据表
linux·运维·mysql