间隙锁

间隙锁:用范围条件检索数据时,并请求共享锁或排他锁时,InnoDB都会给符合条件的已有记录的索引项添加锁,对于键值在条件范围内但表中不存在的记录,就叫做间隙(GAP)。InnoDB也会对这个间隙加锁,这种锁机制就叫做间隙锁。
示例如下。以student表为例,表内容如图所示:
这里写图片描述

打开两个session窗口1会话,两个会话中都关闭事务自动提交,给为手动提交

>set autocommit=false;

在session会话窗口1中,把年纪大于25岁,并且小于28岁的记录,class设置4
(此时没有手动commit):

 >update student set class=4 where age>25 and age<28;

在session窗口2会话中,插入一条年纪为27的记录,该记录正好满足session窗口1中的检索记录:

>insert into student values(9, 4, 'Tari', 27, 1);

执行完session窗口1中的更新语句,立即执行session窗口2中的插入语句,发现session窗口2中的插入语句阻塞
这里写图片描述
会话1中的更新语句,检索的范围是年纪大于25并小于28的,即会给年纪为26、27对应的索引记录上加锁,即使表中没有对应的数据行。正好会话2中的插入语句检索的数据行正式年纪等于27的,此时student表中年纪大于25并小于28已经加上了范围锁,因此会话2中的插入语句阻塞,如果阻塞超时自动退出。
然后会话1中的更新操作后,手动'commit'进行事务提交,则会话2中的插入语句解除阻塞,执行插入成功
这里写图片描述

最后会话2中的插入语句执行完后,手动'commit'进行事务提交,最后数据如下:
这里写图片描述

总结:当一个会话按范围条件进行检索时,会锁住整个范围内所有的索引键值,即使这个键值并不存在,从而造成某些无辜的键值被锁定,导致其他session不能插入该范围内的值,在并发情况下,导致执行效率下降。

猜你喜欢

转载自blog.csdn.net/u010502101/article/details/81430023