MySQL学习笔记 - 5 - 行级锁与两阶段锁协议

2,355 阅读2分钟

行锁

行锁由存储引擎自己实现,不是所有存储引擎都支持行锁(比如MyISAM)

行锁实际上锁的是索引上的记录

间隙锁

  • 间隙锁是对索引记录之前的间隙的锁,或者是对第一个索引记录到最后一个索引记录之间的间隙的锁

  • 间隙锁可能跨越单个索引记录,多个索引记录,或者是没有索引记录

  • 间隙锁是性能和并发之间权衡的一部分,用于某些事务隔离级别(可重复读)

  • 对于同一个间隙,不同事务都可以持有该间隙的间隙锁(可共存的)

一个事务获取了某个间隙的间隙锁以后,并不会阻塞其它事务获取该间隙的间隙锁

  • 间隙锁的目的仅仅是为了阻止其它事务对间隙的插入操作

  • 间隙锁可以显示关闭

通过设置事务隔离级别为读提交;或者启动参数innodb_locks_unsafe_for_binlog(默认情况下是关闭的)

间隙锁的出现是为了要解决在可重复读的事务隔离级别下的幻读问题!!

next-key lock

  • next-key lock由行锁和间隙锁组成
  • next-key lock 是索引记录上的行锁加上索引记录前的间隙上的间隙锁

如果一个索引值包含10,11,13和20,那么next-key lock的加锁区间可能是:

  • (负无穷, 10]
  • (10, 11]
  • (11, 13]
  • (13, 20]
  • (20, 正无穷)

InnoDB行级锁加锁的单位是next-key lock

两阶段锁协议(Two-Pahse Locking -- 2PL)

两阶段锁协议规定所有的事务应遵守的规则:

  1. 在对任何数据进行读写操作之前,首先要申请并获得对该数据的封锁
  2. 在释放一个封锁之后,事务不再申请和获得其它任何封锁

即事务的执行分为两个阶段:

  1. 第一阶段是获取封锁的阶段,称为扩展阶段
  2. 第二阶段是释放封锁的阶段,称为收缩阶段

在InnoDB事务中,行锁在需要的时候才加上,但是并不是不需要了就立马释放,而是要等到事务结束才会释放

如果一个事务需要锁多个行,要把最可能造成锁冲突,最可能影响并发的锁尽量往后放