行锁分为 Record Lock、Gap Lock、Next-Key Lock 和插入意向锁。
Next-Key Lock
行锁和间隙锁的合称,是一个前开后闭区间。
Record Lock
行锁,只锁一行记录,那么导致的问题就是幻读。
Gap Lock
间隙锁,锁住两行记录之间的间隙。
需要注意的是,间隙锁之间是不冲突的。间隙锁的目的是锁住,不允许在间隙中插入数据。
所以间隙锁之间是不冲突的,只和插入操作冲突。
因此,如果两个 session 最开始 update 占据了间隙锁后,又都尝试向其中插入数据,就会互相卡死。
间隙锁并非只在二级索引上生效,在主键索引上同样存在。
间隙锁只会在当前读操作(如 SELECT FOR UPDATE、UPDATE、DELETE 等)时,在 REPEATABLE READ 或 SERIALIZABLE 隔离级别下使用。普通 select 并不会添加,因此可能出现幻读情况 —— 转转技术 中“MySQL 怎么出现幻读啦!”部分。
行锁的两阶段锁协议
InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。
有什么帮助呢?那就是,如果事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁尽量往后放。
进一步了解,可以看一下间隙锁导致的死锁情况、行级锁的加锁规则与案例分析。