一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情。
根据加锁的范围,MySQL 里面的锁大致可以分为:全局锁、表级锁、行锁三类。今天学习一下行锁。 MySQL 的行锁,是由引擎层实现的,InnoDB 支持行锁,而 MyISAM 不支持行锁,这也是 MyISAM 被 InnoDB 替代的重要原因之一。
因为支持行锁,意味着同一时刻可以支持更高的并发度。
行锁之独占和共享
-
共享锁(读锁,S 锁)
共享锁,允许持有锁的事务进行读取。
select ... lock in share mode; insert into ... select ...;以上语句会对 select 的表上,扫描到的数据加共享锁,数据行被事务添加共享锁后,其它事务可以添加共享锁,但是不能添加独占锁。
-
独占锁(写锁,X 锁)
独占锁,允许持有锁的事务进行更新、删除。
update...; delete...; select... for update;数据行被添加独占锁后,其它事务不能再为数据行添加任意类型的锁。
间隙锁
间隙锁(Gap Lock)存在于可重复读隔离级别,为了解决幻读。
间隙锁是对索引记录之间的间隙的锁定。
间隙锁之间不冲突,和间隙锁冲突的是插入意向锁。
-
NEXT-KEY Lock
间隙锁和行锁合称 NEXT-KEY Lock,它是前开后闭区间,锁定一个范围以及记录本身。InnoDB 默认使用它来实现范围的锁定。
-
插入意向锁
由 insert 操作在插入行之前设置的一种间隙锁。
Predicate Locks
InnoDB 支持对包含空间列的列进行 SPATIAL 索引。
为了支持具有 SPATIAL 索引的表的隔离级别,InnoDB 引入了 Predicate Locks。
两阶段锁协议
在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。
如何利用?
如果你的事务中需要锁多个行,要把最有可能造成锁冲突、最有可能影响并发度的锁尽量往后放。
总结
读提交隔离级别下,锁的范围更小,锁的时间更短,如果业务场景符合,建议使用读提交隔离级别。
参考文档
《网易云课堂》
《MySQL 实战 45 讲》