InnoDB 锁的种类之意向锁、记录锁和间隙锁
意向锁(Intention Locks; table-level lock)
意向锁是一种特殊的表级锁,意向锁是为了让 InnoDB 多粒度的锁能共存而设计的。取得行的共享锁和排他锁之前需要先取得表的意向共享锁(IS)和意向排他锁(IX),意向共享锁和意向排他锁都是系统自动添加和自动释放的,整个过程无需人工干预。
意向锁就是指未来的某一个时刻事务可能要加共享锁或者排它锁,提前声明一个意向,分为两种:
意向共享锁(Intention Shared Lock) IS
事务有意向对表中的某些行加共享锁(S锁)
-- 事务要获取某些行的 S 锁,必须先获得表的 IS 锁。
SELECT column FROM table ... LOCK IN SHARE MODE;
意向排它锁(Intention Exclusive Lock)IX
事务有意向对表中的某些行加排他锁(X锁)
-- 事务要获取某些行的 X 锁,必须先获得表的 IX 锁。
SELECT column FROM table ... FOR UPDATE;
举例
-- 要设置 IS 锁 --
select * from A where id = 1 lock in share mode;
-- 要设置 IX 锁 --
select * from A where id > 0 for update;
如果示例 1 和 2 都开启了事务,事务 1 锁住了表 A 的其中 id=1 的一行,事务 2 要获取整个表的更新锁需要进行判断
step1:判断表 A 是否有表级锁
step2:判断表 A 每一行是否有行级锁
当数据量庞大的时候 step2 这种判断十分低效,于是就有意向锁协议
意向锁协议:
事务要获取表 A 某些行的 S 锁必须要获取表 A 的 IS 锁
事务要获取表 A 某些行的 X 锁必须要获取表 A 的 IX 锁
这时候 step2 就改变成了对意向锁的判断
step2:发现表 A 有 IS 锁,说明表 A 肯定有行级的 S 锁,因此,事务 B 申请写锁阻塞等待,判断效率极大提高
记录锁(Record Locks)
官方原文
A record lock is a lock on an index record. For example, SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE; prevents any other transaction from inserting, updating, or d