# 系列目录

# 参考

# InnoDB 锁

数据库遵循的是两段锁协议,将事务分成两个阶段,加锁阶段和解锁阶段(所以叫两段锁)

  • 加锁阶段:在该阶段可以进行加锁操作。加锁不成功,则事务进入等待状态,直到加锁成功才继续执行。
  • 解锁阶段:当事务释放了一个封锁以后,事务进入解锁阶段,在该阶段只能进行解锁操作不能再进行加锁操作。

这种方式虽然无法避免死锁,但是两段锁协议可以保证事务的并发调度是串行化(串行化很重要,尤其是在数据恢复和备份的时候)的。

# 行锁

InnoDB 实现了两种类型的行级锁:

  • 共享锁 (S):在对任何数据进行读操作之前要申请并获得 S 锁。其它事务可以继续加共享锁,但不能加排它锁;
  • 独占锁 (X):在进行写操作之前要申请并获得 X 锁。其它事务不能再获得任何锁;

# 表锁

InnoDB 支持多粒度锁,因此 S 和 X 锁还可以锁表(如使用 ALTER TABLE 等语句会给表上 X 锁)。

另外还设计了两个意向锁,注意意向锁都是表级的

  • 意向共享锁 (IS):表明事务即将给表中的行设置 S 锁。事务给行加 S 锁前必须获得该表的 IS 锁。
  • 意向排它锁 (IX):表明事务即将给表中的行设置 X 锁。事务给行加 X 锁前必须获得该表的 IX 锁。

综上,MySQL 支持两种行锁和四种表锁。

四种表锁的兼容表如下:

锁类型 X IX S IS
X 冲突 冲突 冲突 冲突
IX 冲突 兼容 冲突 兼容
S 冲突 冲突 兼容 兼容
IS 冲突 兼容 兼容 兼容

总结一下就是:

  • 意向锁之间相互不冲突
  • 互斥锁和所有锁都冲突
  • 共享锁互斥意向锁冲突

# 行锁的算法

  • Record Locks:锁(单条)记录
  • Rocord Gaps:锁范围
  • Next-Key Locks:锁范围+锁记录