封锁粒度

一般有两种封锁粒度:行级锁以及表级锁。应该尽量只锁定需要修改的那部分数据,而不是所有的资源。锁定的数据量越少,发生锁争用的可能就越小,系统的并发程度就越高。

读写锁

  • 排它锁(Exclusive),简写为 X 锁,又称写锁。
  • 共享锁(Shared),简写为 S 锁,又称读锁。

规定:

  • 一个事务对数据对象 A 加了 X 锁,就可以对 A 进行读取和更新。加锁期间其它事务不能对 A 加任何锁。
  • 一个事务对数据对象 A 加了 S 锁,可以对 A 进行读取操作,但是不能进行更新操作。加锁期间其它事务能对 A 加 S 锁,但是不能加 X 锁。

兼容关系

- X S
X × ×
S ×

意向锁

使用意向锁(Intention Locks)可以更容易地支持多粒度封锁。意向锁是一种不与行级锁冲突表级锁

规定:

  • 一个事务在获得某个数据行对象的 S 锁之前,必须先获得表的 IS 锁或者更强的锁;
  • 一个事务在获得某个数据行对象的 X 锁之前,必须先获得表的 IX 锁。

兼容关系(特别说明,以下是表锁直接的兼容关系)

- X IX S IS
X × × × ×
IX × ×
S × ×
IS ×

说明:

  • 意向锁不会与行级的共享 / 排他锁互斥。IX,IS是表级锁,不会和行级的X,S锁发生冲突。只会和表级的X,S发生冲突。

举例

用户表user:

id name
1 zhangsan
2 lisi
3 wangwu

事务A,更新id为2的用户名

  1. 获取user表上的IX锁;

  2. 获取id=2数据行的X锁。

事务B,查询user表

  1. 检查到user表上用IX锁;

  2. 事务B加锁请求阻塞。

事务C,更新id为1的用户名

  1. 获取user表的IX锁;

  2. 检测到user表有IX锁;

  3. 意向锁不排斥,故事务C获得IX锁;

  4. id=1不存在其他行级锁,获取行级X锁。

说明:若无意向锁,则对于事务B,将要查询表中的行来确定是否存在其他行级锁。