从锁粒度角度:表级锁、行级锁
-
表级锁:对整张表加锁,并发效率低
-
行级锁:只针对当前操作的行记录进行加锁;并发度高,但加锁开销大,且容易出现死锁。针对索引字段
-
记录锁(Record Lock)
对单行记录加锁
-
间隙锁(Gap Lock)
对连续逻辑范围内的记录加锁,不包含记录本身(不锁已存在的记录,只锁范围内不存在的间隙)。避免在记录范围内插入新的记录。
-
临键锁(Next-Key Lock)
Record Lock + Gap Lock。对连续逻辑范围内的记录加锁,包含记录本身。主要为了解决幻读问题。
举例:
-
主键等值查询,数据存在时退化为 Record Lock
select * from t where id = 10 for update;
Record Lock:锁主键值为10的记录
-
主键等值查询,数据不存在时退化为 Gap Lock
select * from t where id = 11 for update;
Gap Lock:锁住的区间为 (10, 15)
-
主键范围查询
select * from t where id >= 10 and id < 11 for update;
Next-Key Lock:锁住的区间为 [10, 15) <== [10,+∞) ∩ (-∞, 15)
-
-
读写锁
-
共享锁(S锁) = 读锁
-
排他锁(X锁) = 写锁(独占锁)
读写锁总结:表级锁或行级锁都可以是读锁或写锁; 读读不互斥,读写、写写互斥。
意向锁
意向锁是表级锁,用于判断表中是否有行锁。
意向锁分为 意向共享锁(Intention Shared Lock,IS 锁)、意向排他锁(Intention Exclusive Lock,IX 锁)。
意向锁之间互相兼容;与表锁互斥、与行锁不互斥。
锁表流程:需要锁表时,若该表有意向锁或表锁,则无法再锁表,否则可以锁。
锁行流程:先获取意向锁,然后锁行。
意向锁是由数据引擎自己维护的,用户无法手动操作意向锁,在为数据行加共享/排他锁之前,InooDB 会先获取该数据行所在在数据表的对应意向锁。
快照读不加锁 ,这些锁只在当前读起作用。
快照读:普通select语句
当前读:select...for update(排他)、 select...for share(共享)
参考: