共享锁:Shared Locks,S锁。在事务要读取一条记录时,需要先获取该记录的S锁
独享锁(排他锁):Exclusive Locks,X锁。事务要改动一条记录时,需要先获取X锁
S锁与S锁是兼容的;S锁与X锁是不兼容;X锁与X锁也是不兼容。
加S锁
select ... lock in share mode;
X锁
select ... for update;
表锁
意向共享锁:Intention Shared Lock,IS锁。当事务准备在某条记录上加S锁时,需要先在表级别加一个IS锁
意向独占锁:Intention Exclusive Lock,IX锁。当事务准备在某条记录上加X锁时,需要现在表级别加一个IX锁
IS,IX是表级锁,它们的提出是为了在之后加表级别的S锁和X锁可以快速判断表中的记录是否被上锁,避免用遍历的方式查看表中有没有上锁的记录,IS 和 IX 锁是兼容的,IX 和 IX 是兼容的。
兼容性SISXIX
S兼容兼容不兼容不兼容
IS兼容兼容不兼容兼容
X不兼容不兼容不兼容不兼容
IX不兼容兼容不兼容兼容
行锁
Record Locks:(单个行记录上的锁)
有S和X锁之分
一个事务获取了S,其他事务可以获取S,不可以获取X。
一个事务获取了X,其他事务不能获取S,也不能获取X
Gap Locks:(间隙锁)
解决幻读:可使用mvcc,也可采用加锁解决。
如果某条加了Gap锁,不允许其他事务在该条记录之前插入新记录。
那对于最后一条记录之后的间隙怎么办?
数据页有两条伪记录:
Infimum记录:该页面最小的记录
Supremum记录:该页面最大的记录
为了防止其他事务在最后一条记录之后插入,可以给索引中最后一条记录,最后一条记录所在页面的Supremum记录加上一个Gap锁。
Next-Key Locks
既能锁住该记录,也能防止其他事务在该记录前的间隙插入新记录。
其实就是上述两个合体。
Insert Intention Locks:
事务在等待的时候也需要一个锁结构,表明有事务想在某个间隙中插入新纪录,但现在在等待。
例子:T1有Gap锁,T2、T3需要在在T1之前插入,T2、T3就需要生成一个插入意向锁并处于等待状态。T1提交后,T2、T3能获取对象的插入意向锁了,T2、T3不会相互阻塞,可以同时获取插入意向锁,然后执行插入操作。
插入意向锁不会阻止别的事务继续获取该记录上任何类型的锁
隐式锁
一个事务在insert操作时,如果插入的间隙被其他事务加了gap锁,那么本次会被阻塞,当前事务会在该间隙上插入一个插入意向锁。一般情况下不加锁。