最近学完next-key,有点搞不清什么时候会使用next-key,什么时候会降级为行锁,所以测试了一下,归纳一下。
普通索引参考的文章:
MySQL使用普通索引检索时产生的next-key lock和gap lock的范围测试
想要自己测试的朋友可以参考一下改文章的做法。
本文用的数据以10为间隔,[0,100]。
测试环境:
RR可重复读级别下,会触发next-key lock ,
即以下这些情况 ,本文统一以"查询"为例,但其他操作都是一样的
select .. for update
select .. in share mode
update
insert
delete
至于无索引、索引失效的情况,本文不讨论,那些都是转为表锁的。
先说个总的结论:
普通索引是锁左不锁右,即[a,b)
而唯一索引则相反, 锁右不锁左 ,即(a,b]
普通索引
-
=
普通索引的处理比较简单:
假设
= x
,无论x
这条记录是否存在表中,都是锁上相邻记录这里的相邻记录,指的是两端的记录,
eg: x=10 , 表中上一条记录为0, 下一条记录为20,锁上 [0,20)
注意,这里**右端是取不到的**,本文称之为"锁左不锁右"
# 事务1查询条件 事务2被阻塞的锁定范围 1 x=10 [0, 20) 2 x=13 [10, 20) 所以操作
x=20
的数据,比如插入或者删除,都是不会阻塞的 -
in
其实
in
所做的操作就是把每个值,作为单独的一个等值查询操作,再把产生的锁定范围取并集eg:
x in (a,b)
, 等价于(x = a) U (x=b)
# 事务1查询条件 事务2被阻塞的锁定范围 3 j in(10, 40) [0, 20) union [30, 50) 4 j in(10, 45) [0, 20) union [40, 50) 5<