当前位置: 首页 > ops >正文

MySQL独占间隙锁为什么会互相兼容?

如标题疑惑,对于下面SQL:

select id from t order where order_no = 1007 for update

假设这里的order_no是二级索引,并且表中只有

(id,order_no):(1,1001)、(2,1002)、(3,1003)、(4,1004)、(5,1005)、(6,1006)这六个数据。

那刚刚A事务执行的select id from t order where order_no = 1007 for update 语句就会在order_no索引上加一个(1006,+∞)区间的独占间隙锁(注意,这里是RR级别时才会加独占间隙锁锁,如果级别为读已提交RC,那找不到对应的记录时,就会自动释放锁,这也就是为什么RC级别性能好但是无法解决幻读的原因)

但是,如果此时B事务也执行select id from t order where order_no = 1008 for update 语句,也会持有(1006,+∞)区间的独占间隙锁

那,独占体现在哪里呢,为什么A、B事务都可以同时持有独占间隙锁?

​独占间隙锁的独占​

不是排斥其他事务的间隙锁​​,而是排斥其他事务的 ​插入操作​​(插入意向锁)。

多个事务可以同时持有同一个间隙的锁,但它们会​​互相阻塞插入操作​​。

那么,插入意向锁是什么?

插入意向锁是一种特殊的​​间隙锁​​,表示“​​准备在这个间隙插入一条记录​​”,如果A事务想要在(1006,+∞)区间插入一条数据,但是对应的这个间隙被B事务或其他事务持有这个独占间隙锁,那插入就会阻塞等待。

如果A事务想要插入一条数据,这个间隙的独占间隙锁被当前自己这个事务持有了,那插入就不会被阻塞(别人持有间隙锁就阻塞,自己持有间隙锁或者没有间隙锁,那插入就不会阻塞)

这也是为什么小林大佬的这幅图中会出现死锁的现象,原因就是独占间隙锁是可以多事务持有的(猜测是为了更好的并发性能吧),但是插入意向锁对应间隙的间隙锁又不能被其他事务持有,这才导致了死锁发生(互相等待释放间隙锁)

Q:从理论学习来看,应该是写写互斥、写读互斥、读读不互斥,但是这里看起来像独占间隙锁被多个事务持有,那独占间隙锁和共享间隙锁,有什么不一样吗?

A:

        这里MySQL的设计是一个伪互斥,其实一个区间如果申请了独占间隙锁lock1,在这个区间申请独占间隙锁lock2还是会被阻塞的,只不过是采用A事务申请被持有lock1的引用,B事务也持有这个lock1的引用这种方式实现的。

        因此,独占间隙锁和共享间隙锁,其他从功能来看都是一样的,都是加了间隙锁,而防止插入操作的发生,从而避免了幻读。

        唯一不一样可能就是语义了,独占更强调是"我要修改数据,别打扰",共享更强调"我要读数据,别打扰"

http://www.xdnf.cn/news/19219.html

相关文章:

  • 慢SQL优化
  • SQL 学习
  • 以声为剑,绘山河热血——刘洋洋《不惧》8月30日全网上线
  • 逆向思维下,如何把基金投资做亏?
  • 算法 --- 前缀和
  • 一文了解大模型微调
  • AWD相关知识
  • 【Python】国内可用的高速pip镜像源大全
  • 蓝牙5.3核心技术架构解析:从控制器到主机的无线通信设计
  • 知识随记-----Qt 样式表深度解析:何时需要重写 paintEvent 让 QSS 生效
  • 鸿蒙ArkTS 核心篇-15-条件渲染(组件)
  • 如何改变传统教育的消费习惯-第三代结束-第四代开启
  • 源码解析-时间轮[HashedWheelTimer]
  • 项目管理方法如何选择
  • Python实现京东商品数据自动化采集的实用指南
  • 水库/油箱/化工罐区...无线液位控制系统如何实现远程监控?
  • C++ constexpr:编译时计算的高效秘籍
  • 动态规划--Day05--最大子数组和--53. 最大子数组和,2606. 找到最大开销的子字符串,1749. 任意子数组和的绝对值的最大值
  • 音视频学习(六十):H264中的PPS
  • 基于Kubernetes Operator的自动化运维平台设计与实践
  • Ethan开发者创新项目日报 | 2025-08-30
  • OpenGeode 综合介绍(基于 GitHub 仓库)
  • pikachu之XSS
  • JavaWeb前端06(ElementPlus快速构建网页)
  • JavaScript 一些进阶知识点与注意事项
  • Python可视化与交互-matplotlib库
  • 仓颉编程语言青少年基础教程:程序基本结构和语言特点
  • 【leetcode】112. 路径总和
  • # `std::basic_istream`总结
  • 基于 MyBatis-Plus 拦截器实现“结账后禁止修改”的优雅方案