参考:https://www.jianshu.com/p/13f5777966dd
http://guitoo.cc/wordpress/2019/05/07/mysql是如何处理间隙锁的加锁规则/

锁是为了防止对数据争用出现错误的一种机制,在mysql中锁是以事务为单位,只有提交或者回滚了事务才会释放锁。

在innodb存储引擎中

行级锁

  1. 共享锁(s lock) 允许事务读取一条记录

  2. 排他锁(x lock) 允许事务删除或更新一条记录

共享锁可以多个事务同时获取,排他锁与任何锁都不能共存

X S
X 互斥 互斥
S 互斥 共享
由于是行级锁所以共享互斥都是对某一条特定的记录并不是整个表库
mysql对于insert、update、delete都会增加xLock;
如果对于查询操作加锁 for update 加x lock, lock in share mode加s lock,但是没加锁的select不会进行阻塞。

mysql是对索引加索,1、如果查询条件不是索引那么将使用表锁 2、如果使用了同一个索引但不是同一条数据时也会阻塞

意向锁

意向锁是获取行锁时提前获取到的表锁,以避免其他事务想要获取表锁时需要全表扫描确定是否已被获取行锁

  1. 共享锁(is lock) 事务想要获取表中的几行数据的共享锁

  2. 排他锁(ix lock) 事务想要获取表中的几行数据的排他锁

意向锁只与表锁发生冲突,冲突情况如下

X IX S IS
X Conflict Conflict Conflict Conflict
IX Conflict Compatible Conflict Compatible
S Conflict Conflict Compatible Compatible
IS Conflict Compatible Compatible Compatible

gap lock(间隙锁)

左开右开区间锁,可以避免幻读

next-key lock (临界锁)

左开右闭区间的锁,即间隙锁+临界锁

加锁

对于select * from table where id = 10 for update 这条sql,在a列的不同情况下会有不同的加锁情况
以下都是在rr隔离级级别下且允许间隙锁时:

1、id为主键
直接在id=10聚簇索引上加行锁,没有就不加锁

2、id为唯一索引
在id=10辅助索引上加行锁并在对应的主键上加行锁,没有就不加锁

3、id为普通索引
会给辅助索引加上临界锁,如果没有id=10这个值会退化为间隙锁
比如:id值为 1、3、5、10、11、12时就会加上 (5,10】,(10,11)这两个锁,并且对相关聚簇索引加上行锁
id值为1、3、5、9、11、12时就会加上 (9,11)一个锁

4、id不是索引
无论存不存在都会加表锁(是否存在优化??

posted @ 2021-02-23 18:56  犬犬呀  阅读(19)  评论(0)    收藏  举报