文章目录
我自己总结,InnoDB锁的特点是多粒度共存、服务于特定的事务隔离级别。
此外,可以梳理出“锁”存在的目的:
- 在Read Commit(提交读)级别上,需要解决的问题是脏读。
- 在Repeatable Read(可重复读)级别上,需要解决的问题是脏读以及幻读,
最后是在满足事务隔离级别的前提下,提高性能:
- 利用MVCC多版本并发控制提高读取性能。
- 特定情况下,升级、降级锁,例如在唯一主键的情况下,将下一键锁降为记录锁;或者在想要获取一个表中的行锁时,先利用意向锁这个逻辑上更高一级别的锁去检验是否能够获取。
InnoDB的常用锁如下:
共享锁和排他锁
MySql在行锁的实现上有两种级别:共享锁S和排他锁X。
- 共享锁允许持有锁的事务读取该行的事务
- 排他锁允许持有锁的事务更新或者删除该行
如果事务A对某行持有共享锁,那么事务B申请锁时,流程如下:
- 事务B对该行申请的共享锁会很快被通过,A和B将同时持有该行的共享锁
- 事务B如果申请排他锁,则无法立即得到权限。
如果A获取了某行的排他锁,那么事务B无论想要获取哪种锁,都必须等待A先释放。
共享锁可以分为行锁和表锁,是行为逻辑上的概念。
Intention Locks 意向锁
InnoDB支持多种粒度的锁定,也就是行锁和表锁可以共存。意向锁是支持这个特点的基石。
意向锁可以理解是表级别的锁,不是程序员手动设置的锁,而是InnoDB在替事务申请行锁、表锁过程中的衍生。意向锁有两种
- 意图共享锁IS,事务打算设置针对表中的一些行设置共享锁时触发,语句
SELECT ... FOR SHARE
- 意图独占锁IX,事务打算在表中的某些行设置排他锁时触发,
SELECT ... FOR UPDATE
此外,另外两种实际存在的表级别的锁是
- 表级别的共享锁