聚簇索引 , 查询命中聚簇索引就是 InnoDB 存储引擎下的主键索引 , 具体可参考《MySQL索引》 。
下图展示了使用 UPDATE book SET score = 9.2 WHERE ID = 10 语句命中的情况下在 RC 和 RR 隔离等级下的加锁 , 两种隔离等级下没有任何区别 , 都是对 ID = 10 这个索引加排他记录锁 。

文章插图
聚簇索引 , 查询未命中下图展示了 UPDATE book SET score = 9.2 WHERE ID = 16 语句未命中时 RR 隔离级别下的加锁情况 。
在 RC 隔离等级下 , 不需要加锁;而在 RR 隔离级别会在 ID = 16 前后两个索引之间加上间隙锁 。

文章插图
值得注意的是 , 间隙锁和间隙锁之间是互不冲突的 , 间隙锁唯一的作用就是为了防止其他事务的插入新行 , 导致幻读 , 所以加间隙 S 锁和加间隙 X 锁没有任何区别 。
二级唯一索引 , 查询命中下图展示了 UPDATE book SET score = 9.2 WHERE ISBN = 'N0003' 在 RC 和 RR 隔离等级下命中时的加锁情况 。
在 InnoDB 存储引擎中 , 二级索引的叶子节点保存着主键索引的值 , 然后再拿主键索引去获取真正的数据行 , 所以在这种情况下 , 二级索引和主键索引都会加排他记录锁 。

文章插图
二级唯一索引 , 查询未命中下图展示了 UPDATE book SET score = 9.2 WHERE ISBN = 'N0008' 语句在 RR 隔离等级下未命中时的加锁情况 , RC 隔离等级下该语句未命中不会加锁 。
因为 N0008 大于 N0007 , 所以要锁住 (N0007,正无穷)这段区间 , 而 InnoDB 的索引一般都使用 Suprenum Record 和 Infimum Record 来分别表示记录的上下边界 。Infimum 是比该页中任何记录都要小的值 , 而 Supremum 比该页中最大的记录值还要大 , 这两条记录在创建页的时候就有了 , 并且不会删除 。
所以 , 在 N0007 和 Suprenum Record 之间加了间隙锁 。

文章插图
为什么不在主键上也加 GAP 锁呢?欢迎留言说出你的想法 。
二级非唯一索引 , 查询命中下图展示了 UPDATE book SET score = 9.2 WHERE Author = 'Tom' 语句在 RC 隔离等级下命中时的加锁情况 。
我们可以看到 , 在 RC 等级下 , 二级唯一索引和二级非唯一索引的加锁情况是一致的 , 都是在涉及的二级索引和对应的主键索引上加上排他记录锁 。

文章插图
但是在 RR 隔离等级下 , 加锁的情况产生了变化 , 它不仅对涉及的二级索引和主键索引加了排他记录锁 , 还在非唯一二级索引上加了三个间隙锁 , 锁住了两个 Tom 索引值相关的三个范围 。
那为什么唯一索引不需要加间隙锁呢?间隙锁的作用是为了解决幻读 , 防止其他事务插入相同索引值的记录 , 而唯一索引和主键约束都已经保证了该索引值肯定只有一条记录 , 所以无需加间隙锁 。

文章插图
需要注意的是 , 上图虽然画着 4 个记录锁 , 三个间隙锁 , 但是实际上间隙锁和它右侧的记录锁会合并成 Next-Key 锁 。
所以实际情况有两个 Next-Key 锁 , 一个间隙锁(Tom60,正无穷)和两个记录锁 。
二级非唯一索引 , 查询未命中下图展示了 UPDATE book SET score = 9.2 WHERE Author = 'Sarah' 在 RR 隔离等级下未命中的加锁情况 , 它会在二级索引 Rose 和 Tom 之间加间隙锁 。而 RC 隔离等级下不需要加锁 。

文章插图
无索引当 Where 从句的条件并不使用索引时 , 则会对全表进行扫描 , 在 RC 隔离等级下对所有的数据加排他记录锁 。在RR 隔离等级下 , 除了给记录加锁 , 还会对记录和记录之间加间隙锁 。和上边一样 , 间隙锁会和左侧的记录锁合并成 Next-Key 锁 。
下图就是 UPDATE book SET score = 9.2 WHERE score = 22 语句在两种隔离等级下的加锁情况 。
推荐阅读
- 互动直播中的前端技术——即时通讯
- 茶叶在旅行中的作用,白茶的保健功效介绍
- 富士康|为什么职场中有人错把平台当本事?
- 干粉灭火器的压把怎样才能按下去?
- 底妆怎么画才精致?手把手教会你
- 橘皮红茶是如何制作的?[红茶]
- 敦煌月牙泉其中的水,辨证茶疗与疾病的关系
- 请把风水当回事 好房子好风水的内部布局合理
- 淘宝店铺规划方案 淘宝店铺定价策略
- 人的身材在一天中的什么时候最高?
