InnoDB中的行级锁

2021.03.17 07:03 218
阅读约 4 分钟

锁的类型

InnoDB实现了两种标准的行级锁:

  • 共享锁(S Lock):允许事务读取数据。
  • 排他锁(X Lock):允许事务删除或者更新一行数据。

锁的算法

InnoDB引擎有三种行锁的算法设计,分别是:

  • Record Lock:单个行记录上的锁
  • Gap Lock:间隙锁,锁定一个范围,但不包含记录本身。
  • Next-Key Lock:Gap Lock + Record Lock,锁定一个范围,并且锁定记录本身。

Record Lock总是会锁住索引记录,如果InnoDB引擎表建立时没有设置任何索引,这时InnoDB引擎会使用隐式的主键来进行锁定。

Next-Key Lock结合了记录锁与间隙锁的一种锁定算法,InnoDB对于行的查询都采用这种算法。对于不同的sql语句,可能设置共享(Share)的Next-Key Lock和排他的(Exlusive)Next-Key Lock。

可以通过如下例子演示范围查询时Next-Key Lock的区间锁定,建立一张表t

create Table t(a int, primary key(a)) ENGINE = InnoDB;

插入值为1,2,3,4,7,8的六条记录,接着开启两个事务:

时间

事务1

事务2

1begin; 
2Select * from t where a < 6 lock in share mode;begin;
3 insert into t select 5(或者6)
4 阻塞

在这种情况下,无论插入的是5还是6,都会被锁定。因为Next-Key Lock锁定的是(-∞,6)这个区间的所有数值。

对于单个值的查询,不需要用到Gap Lock,只需要使用Record Lock即可。同样对上面的表t执行下面两个事务。

时间

事务1

事务2

1begin; 
2Select * from t where a = 7 lock in share mode;begin;
3 insert into t select 5(或者6)
4 成功

这时插入记录5和6都是可行的。需注意只有在RR隔离级别下,Next-key Lock才是默认的行记录锁定算法。

InnodDB中使用Next-key Lock来避免不可重复读的问题,Next-key Lock不仅仅锁住扫描到的索引,而且还锁住这些索引覆盖的范围,因此对这个范围内的插入都是不允许的。这就避免了另一个事务插入数据导致的不可重复读问题。


 

字数:948 发布于 6 个月前
Copyright 2018-2021 Siques