昨天看了realzyy兄的一篇文章一个关于主键排他锁的问题,觉得很有意思,然后做了一些实验:
环境基本一样(MySQL default transaction isolation level is REPEATABLE READ),将原来的(20,20)这个记录改为(8,8),其实这个改动没有什么意义(鄙视一下自己)。
先是删除5的这条记录,等于变成(1,1),(2,2),(3,3),(4,4),(6,6),(7,7),(8,8).
1.然后session1 begin;select … for update;
2.接着session2 insert 5 这条记录,看是否能插入,还是hanging.
1这步的条件和相应能否插入的结果是:
① <=4 hanging
② <=5 hanging
③ < 5 hanging
④ >=6 success!
⑤ >=5 hanging
⑥ > 5 hanging
⑦ =4 success!
⑧ =6 success!
⑨ 将<=4这样的范围查找替换成单个查找并union all以后是success!
InnoDB参考手册上这么说:REPEATABLE READ 这是 InnoDB 默认的事务隔离级。. SELECT … FOR UPDATE, SELECT … LOCK IN SHARE MODE, UPDATE, 和 DELETE ,这些以唯一条件搜索唯一索引的,只锁定所找到的索引记录,而不锁定该索引之前的间隙。 否则这些操作将使用 next-key 锁定,以 next-key 和 gap locks 锁定找到的索引范围,并阻塞其它用户的新建插入。
以上的解释只能解释⑦⑧⑨,感觉①-⑥这种range search还是使用了next-key 和 gap locks 锁定(next-key 和 gap locks是针对搜索条件中有涉及主键索引而言),而且④居然还是个特例。
标签: gap lock, MySQL, next-key lock