什么是间隙锁
当我们用范围条件而不是相等条件检索数据,并请求共享 或排他锁时,InnoDB 会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但不存在的记录,叫做“间隙 (GAP)”,InnoDB 也会对这个“间隙”加锁,这种锁机制加锁所谓的间隙锁 (NEXT-KEY) 锁。
危害:因为 Query 执行过程中通过范围查找的话,他会锁定整个范围内所有的索引键值,即使这个键值并不存在。间隙锁有一个比较致命的弱点,就是当锁定一个范围键值之后,即使某些不存在的键值也会被无辜的锁定,而造成在锁定的时候无法插入锁定值范围内的任何数据,在某些场景下这可能会针对性造成很大的危害。
测试
注意表中的数据,id 是 1,2,4,5,7,8 缺少了 3,6 ,没有连续 id 号。
事务顺序 | 事务1 | 事务2 |
---|---|---|
① | begin; | |
② | select * from user where id between 1 and 5 for update; | |
③ | begin; | |
④ | insert into user (id,username,age,sex)values(3,‘wangwu’,20,1); | |
⑤ | commit; | commit; |
运行结果:
可以看到,事务2在执行新增 id 为 3 的数据时出现了锁等待现象。说明 id 为 3 的数据被事务1进行的范围查询加锁锁住,其他事务需要等到事务1进行提交或者回滚之后才能继续操作事务1锁住的数据。