mysql的锁类型
(1) 共享/排它锁(Shared and Exclusive Locks)
共享锁(读锁/S 锁)是为了当前事务去读一行数据 ,其他事务可以并发读取数据,但不能对该数据行进行增删改[也就是不能加排他锁],直到已释放所有共享锁(在查询语句后面增加LOCK IN SHARE MODE)
排他锁 (写锁/X 锁) 是为了让当前事务去修改或删除某一行数据,其他事务不能对该数据行进行增删改查(在查询语句后面增加FOR UPDATE)
注意点
- 对于 insert、update、delete,InnoDB 会自动给涉及的数据加排他锁(X),只有查询 select 需要我们手动设置排他锁
- 对于一般的 select 语句,InnoDB 不会加任何锁,也就是可以多个并发去进行 select 的操作,不会有任何的锁冲突,因为根本没有锁
(2)意向锁🔒(Intention Locks)
意向锁的意义在于,使得行锁和表锁能够共存。其设计目的主要是为了在一个事务中揭示下一行将要被请求锁的类型。
意向共享锁(IS):如果需要对记录 A 加共享锁,那么此时 InnoDB 会先找到这张表,对该表加意向共享锁之后,再对记录 A 添加共享锁(也就是说一个数据行加共享锁前必须先取得该表的 IS 锁) 意向排他锁(IX):如果需要对记录 A 加排他锁,那么此时 InnoDB 会先找到这张表,对该表加意向排他锁之后,再对记录 A 添加排他锁(也就是说事务在给一个数据行加排他锁前必须先取得该表的 IX 锁) 意向锁是 InnoDB 自动加的,不需要用户干预。
(3) 记录锁(Record Locks)
记录锁是索引记录上的锁,例如:SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE;会阻止其他事务对c1=10的数据行进行插入、更新、删除等操作。
记录锁总是锁定索引记录。如果一个表没有定义索引,那么就会去锁定隐式的“聚集索引”。
(4) 间隙锁(Gap Locks)
间隙锁锁住一个间隙以防止被插入。
假设索引列2,4,8三个值,如果对4加锁,那么也会同时对(2,4) 和(4,8)这两个间隙加锁,其他事务无法插入索引值在这两个间隙之间的记录。
注意:
- 如果索引是唯一索引,那么只会锁住这一条记录,不会锁住间隙
- 对于联合索引且是唯一索引,如果where条件只包括联合索引的一部分,那么依然会加间隙锁
解释: 关键字UNIQUE可以把它定义为一个唯一索引。
(5) 临键锁(Next-key Locks)
Next-Key Locks是行锁与间隙锁的组合。当InnoDB扫描索引记录的时候,会首先对选中的索引记录加上记录锁(Record Lock),然后再对索引记录两边的间隙加上间隙锁(Gap Lock)。
索引列2,4,8三个值,那么可能的next-key lock 包括 (负无穷,2] ,(2.4],(4,8],(8,正无穷] 在RR隔离级别下,Innodb使用next-key lock 主要是防止幻读问题产生
(6) 插入意向锁(Insert Intention Locks)
插入意向锁是在数据行插入之前通过插入操作设置的间隙锁定类型。
如果多个事务插入到相同的索引间隙中,如果它们不在间隙中的相同位置插入,则无需等待其他事务。例如:在4和7的索引间隙之间两个事务分别插入5和6,则两个事务不会发冲突阻塞。
