mysql 如何避免间隙锁_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. 不做物理删除, 而做逻辑删除 或者 就 修改.

你可能感兴趣的:(mysql,如何避免间隙锁)