针对非唯一索引等值查询时,查询的记录存不存在,加锁的规则也会不同:
- 当查询的记录「存在」时,由于不是唯一索引,所以肯定存在索引值相同的记录,于是非唯一索引等值查询的过程是一个扫描的过程,直到扫描到第一个不符合条件的二级索引记录就停止扫描,然后在扫描的过程中,对扫描到的二级索引记录加的是 next-key 锁,而对于第一个不符合条件的二级索引记录,该二级索引的 next-key 锁会退化成间隙锁 。同时,在符合查询条件的记录的主键索引上加记录锁 。
- 当查询的记录「不存在」时,扫描到第一条不符合条件的二级索引记录,该二级索引的 next-key 锁会退化成间隙锁 。因为不存在满足查询条件的记录,所以不会对主键索引加锁 。
1、记录不存在的情况
实验一:针对非唯一索引等值查询时,查询的值不存在的情况 。先来说说非唯一索引等值查询时,查询的记录不存在的情况,因为这个比较简单 。
假设事务 A 对非唯一索引(age)进行了等值查询,且表中不存在 age = 25 的记录 。
mysql> begin;Query OK, 0 rows affected (0.00 sec)mysql> select * from user where age = 25 for update;Empty set (0.00 sec)事务 A 加锁变化过程如下:- 定位到第一条不符合查询条件的二级索引记录,即扫描到 age = 39,于是该二级索引的 next-key 锁会退化成间隙锁,范围是 (22, 39) 。
- 停止查询

文章插图
我们也可以通过
select * from performance_schema.data_locks\G; 这条语句来看看事务 A 加了什么锁 。输出结果如下,我这里只截取了行级锁的内容 。

文章插图
从上图的分析,可以看到,事务 A 在 age = 39 记录的二级索引上(INDEX_NAME: index_age ),加了范围为 (22, 39) 的 X 型间隙锁 。
此时,如果有其他事务插入了 age 值为 23、24、25、26、....、38 这些新记录,那么这些插入语句都会发生阻塞 。不过对于插入 age = 39 记录的语句,在一些情况是可以成功插入的,而一些情况则无法成功插入,具体哪些情况,接下来我们就说!
当有一个事务持有二级索引的间隙锁 (22, 39) 时,什么情况下,可以让其他事务的插入 age = 22 或者 age = 39 记录的语句成功?又是什么情况下,插入 age = 22 或者 age = 39 记录时的语句会被阻塞?我们先要清楚,什么情况下插入语句会发生阻塞 。
插入语句在插入一条记录之前,需要先定位到该记录在 B+树 的位置,如果插入的位置的下一条记录的索引上有间隙锁,才会发生阻塞 。
经验总结扩展阅读
- 白芸豆怎么吃减肥 白芸豆怎么吃减肥最佳
- 振腹疗法怎么练 振腹疗法手法训练
- 怎么瘦小腿的肌肉 怎么瘦小腿的肌肉腿
- 视频终端综合征是怎么回事 怎样预防视频终端综合征
- 在家怎么锻炼肌肉是正确的方式 在家怎样锻炼肌肉最有效
- 中国第3座迪士尼会建在哪个城市 为什么总是有相关消息传出
- 鲨鱼肌怎么练 鲨鱼肌怎么练无机械
- 腰部运动后如何做拉伸 腰部运动后怎么拉伸
- wmls是什么意思网络用语
- 他奶奶滴给老子玩阴的是吧是什么梗
