mysql 间隙锁

mysql控制间隙锁的参数是:

:innodb_locks_unsafe_for_binlog,

这个参数默认值是OFF, 也就是启用间隙锁, 他是一个bool值, 当值为true时表示disable间隙锁


间隙锁的出现主要集中在同一个事务中先delete后 insert的情况下,当我们通过一个参数去删除一条记录的时候, 

如果参数在数据库中存在,那么这个时候产生的是普通行锁,锁住这个记录, 然后删除, 然后释放锁。(正常情况)

如果这条记录不存在(非正常情况),问题就来了, 数据库会扫描索引,发现这个记录不存在, 这个时候的delete语句获取到的就是一个间隙锁,

然后数据库会向左扫描扫到第一个比给定参数小的值,向右扫描扫描到第一个比给定参数大的值, 然后以此为界,

构建一个区间, 锁住整个区间内的数据, 一个特别容易出现死锁的间隙锁诞生了。


所以间隙锁 产生于 删除不存在的数据的时候.



在Mysql中, 事务最终都是穿行执行, 但是在高并发的情况下, 

执行的顺序就极有可能发生改变, 变成下面这个样子:


>>> delete from testLock where id = ‘6’;


>>> insert into testLock(id,name) values(‘6’, ‘hahaha’);


这个时候最后一条语句:insert into testLock(id,name) values(‘6’, ‘hahaha’); 执行时就会爆出死锁错误。因为删除id = 6这条记录的时候,

id为6之后的部分都被锁住了, 他们都取得了这一个数据段的共享锁, 所以在获取这个数据段的排它锁时出现死锁。

这种问题的解决办法:前面说了, 通过修改数据库的参数innodb_locaks_unsafe_for_binlog来取消间隙锁从而达到避免

这种情况的死锁的方式尚待商量, 那就只有修改代码逻辑, 存在才删除,尽量不去删除不存在的记录。


mysql 间隙锁 给我们写业务逻辑的提示:

1.删除之前,先查询是否存在. 如果并发不大,内部系统,可以不考虑

2. 不做物理删除, 而做逻辑删除 或者 就 修改.

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容