mysql锁从大方向分为全局锁,表级锁和行锁,这篇文章我们主要讲行锁。
首先,我们需要明确,行锁是innodb引擎特有的,这也是innodb很厉害的一点。
行锁的类型有四种,记录锁,间隙锁,临建锁,插入意向锁
在讲这四种行锁之前,我们需要明确它们的基础,也就是共享锁和排他锁,我们把这两种称为锁的模式
共享锁(S锁):select lock in share mode,满足读读共享,读写互斥
排它锁(X锁):select for update ; update, insert ,delete,满足写写互斥、读写互斥
下图是这两种锁模式的兼容情况
![](https://img.haomeiwen.com/i6360099/bc5a858fb2c3a034.png)
现在回到四种行级锁:
1.记录锁(Record Lock):锁住的是一条记录
2.间隙锁(Gap Lock):只存在于可重复读隔离级别,目的是为了解决可重复读隔离级别下幻读的现象,限制一个区间在间隙锁加锁的情况下不能插入数据,如(3,5),那么锁期间4就无法被插入
产生间隙锁的条件(RR事务隔离级别下;):
使用普通索引锁定;
使用多列唯一索引;
使用唯一索引锁定多行记录。
间隙锁设置:
首先查看 innodb_locks_unsafe_for_binlog 是否禁用:show variables like 'innodb_locks_unsafe_for_binlog';
查看结果:innodb_locks_unsafe_for_binlog:默认值为OFF,即启用间隙锁。
因为此参数是只读模式,如果想要禁用间隙锁,需要修改 my.cnf(windows是my.ini) 重新启动才行。
# 在 my.cnf 里面的[mysqld]添加
[mysqld]
innodb_locks_unsafe_for_binlog = 1
具体事例分析:https://zhuanlan.zhihu.com/p/48269420
3.临建索(Next-Key Lock):目的也是为了解决幻读,是记录锁和行级锁的组合,既可以限制一个区间不能插入数据,还可以限制某行记录不能被修改,如(3,5],那么4无法插入,且5这条记录不能被修改
4.插入意向锁:一个事务在插入一条记录的时候,需要判断插入位置是否已被其他事务加了间隙锁(next-key lock 也包含间隙锁)。如果有的话,插入操作就会发生阻塞,直到拥有间隙锁的那个事务提交为止(释放间隙锁的时刻),在此期间会生成一个插入意向锁,表明有事务想在某个区间插入新记录,但是现在处于等待状态。
参考资料:https://xiaolincoding.com/mysql/lock/mysql_lock.html#%E5%85%A8%E5%B1%80%E9%94%81
网友评论