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(记录锁 + 间隙锁),而非单独的间隙锁或记录锁。
相关推荐
执笔画情ora14 分钟前
Postgresql数据库管理-pg_xact
数据库·postgresql·oracle
南棱笑笑生32 分钟前
20260310在瑞芯微原厂RK3576的Android14查看系统休眠时间
服务器·网络·数据库·rockchip
JuneXcy1 小时前
第4章 Mysql数据操纵语句--单表查询
mysql
XDHCOM1 小时前
ORA-32152报错咋整啊,数据库操作遇到null number问题远程帮忙修复
服务器·数据库·oracle
专利观察员1 小时前
输配电行业创新转型实践:南宁迪**力有限公司的专利策略调整、专利检索工具采用
数据库·科技·专利·专利申请
jgyzl1 小时前
2026.3.9 Redis内存回收内存淘汰
数据库·redis·缓存
白露与泡影1 小时前
MySQL 时间类型选型避坑:timestamp 和 datetime 该怎么选?
数据库·mysql
青槿吖2 小时前
第二篇:告别XML臃肿配置!Spring注解式IOC/DI保姆级教程,从入门到真香
xml·java·开发语言·数据库·后端·sql·spring
运维 小白3 小时前
2. 部署mysql服务并监控mysql
数据库·mysql·adb
聪明人3 小时前
macOS安装Redis
数据库·redis·macos