mysqlwen

mysql主流锁体系回顾

2023-08-16  本文已影响0人  小胖学编程
mysql主流锁.png

1. 锁相关解释

1.1 行级锁定义

记录锁(Record Lock)

间隙锁(Gap Lock)

临键锁(Next-Key Lock)

插入意向锁(Insert Intention Lock)

1.2 加锁情况分析

select * from user where uid=xx for update
索引类型 where语句条件能否匹配到数据 加速情况
uid是唯一索引 排他记录锁
uid是唯一索引 间隙锁
uid是普通索引 临键锁
uid是普通索引 间隙锁
uid是不是索引 不管是否匹配 表锁

1.3 表级锁定义

意向锁

首先,申请意向锁的动作是数据库完成的,也就是说,事务A申请一行行锁的时候,数据库会自动先开始申请表的意向锁。

那么到底意向锁有什么用?

首先,意向锁是——表级锁。
(1)事务A锁住了表中的一行,这一行只能读,不能写。【事务A加了共享锁】
(2)事务B申请整个表的写锁。【请注意:是整个表!!!】
(3)如果事务B申请成功,那么理论上它就能修改表中的任意一行,这与A持有的共享锁时冲突的。【事务A不允许修改】
(4)数据库为避免这种冲突,怎么办的?就是让B的申请阻塞,直到A释放行锁。
解决方案:
step1:判断表是否已被其他事务用表锁锁住。
step2:判断表中每一行是否已经被行锁锁住。

请注意step2,需要遍历整个表。效率实在不高。
改进版:
step1:不变
step2:发现表上有意向共享锁,说明表中有些行被共享行锁锁住了,因此,事务B申请表的写锁会被阻塞。

image

假如一个表被加了意向排他锁(IX),证明此时有事务在修改表中具体某行的数据,那么对应的某行可能加了x锁,1.如果这时候其他事务要再加意向锁,那么可以加成功(因为加了意向锁之后,后续查询或者修改的是某行的数据,这行和上面的x锁未必冲突)所以意向锁之间是兼容的。2.如果此时其他事务加的是全表共享锁S,因为前面表中的数据正在被修改,所以S锁是加不成功的。所以意向排他锁和表共享锁是冲突的。

(敲黑板,划重点)意向锁的作用就是协调行锁和表锁之间的关系的,是将行锁从另一个角度提高到了表锁的等级(伪表锁),与表锁进行判断。
注意:select语句不是加锁!!!

意向锁是InnDB自动加的,不需要用户的干预。

2. 死锁情况

2.1 间隙锁导致思死锁

表中数据uid(1001,1110,1111,1120,1121,1130)。uid是我们的唯一索引。

核心问题:间隙锁是可兼容的,即同一个事务可以在同一个间隙上获取间隙锁。

时刻 事务1 事务2
T1 begin begin
T2 select * from user where uid =1002 for update uid是唯一索引,因此会加上间隙锁(1001,1110)
T3 select * from user where uid =1003 for update uid是唯一索引,因此会加上间隙锁(1001,1110)
T4 insert into user (uid,name,age) values (1002,'tom',12) 此时需要获取插入意向锁,发现1002已经被事务2持有的间隙锁给占了,事务1被阻塞
T5 insert into user (uid,name,age) values (1003,'jackson',13) 此时需要获取插入意向锁,发现1003已经被事务1持有的间隙锁给占了,事务2被阻塞
T6 commit commit

附录

MySql性能(2)— 一文了解所有的mysql隔离级别
MySQL系列-仅靠MVCC就能解决幻读?错!Gap锁了解一下?
MySql性能(4)-mysql锁知多少(表/行锁、共享读锁/独占写锁、共享锁/排他锁、间隙锁、意念锁)

上一篇 下一篇

猜你喜欢

热点阅读