间隙锁 秒速五厘米 2022-05-17 02:21 154阅读 0赞 间隙锁:用范围条件检索数据时,并请求共享锁或排他锁时,InnoDB都会给符合条件的已有记录的索引项添加锁,对于键值在条件范围内但表中不存在的记录,就叫做间隙(GAP)。InnoDB也会对这个间隙加锁,这种锁机制就叫做间隙锁。 示例如下。以student表为例,表内容如图所示: ![这里写图片描述][70] 打开两个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中的插入语句阻塞 ![这里写图片描述][70 1] 会话1中的更新语句,检索的范围是年纪大于25并小于28的,即会给年纪为26、27对应的索引记录上加锁,即使表中没有对应的数据行。正好会话2中的插入语句检索的数据行正式年纪等于27的,此时student表中年纪大于25并小于28已经加上了范围锁,因此会话2中的插入语句阻塞,如果阻塞超时自动退出。 然后会话1中的更新操作后,手动`'commit'`进行事务提交,则会话2中的插入语句解除阻塞,执行插入成功 ![这里写图片描述][70 2] 最后会话2中的插入语句执行完后,手动`'commit'`进行事务提交,最后数据如下: ![这里写图片描述][70 3] 总结:**当一个会话按范围条件进行检索时,会锁住整个范围内所有的索引键值,即使这个键值并不存在,从而造成某些无辜的键值被锁定,导致其他session不能插入该范围内的值,在并发情况下,导致执行效率下降。** [70]: /images/20220517/eb1e479e6d2a48bd84eaa274a14f4409.png [70 1]: /images/20220517/47c2706dc4ef416b82a82e2e724f5962.png [70 2]: /images/20220517/b8cb9d49f7b8455184d38516bd99cd18.png [70 3]: /images/20220517/c16c32af1d1b43b1a7aace2517008115.png
还没有评论,来说两句吧...