MySQL-lock

MySQL中有多种锁类型,包括乐观锁、悲观锁、全局锁、表级锁、页级锁、行级锁、共享锁、排它锁、意向共享锁、意向排它锁、间隙锁、临建锁和记录锁,下面分别介绍一下各种锁:

  1. 乐观锁(Optimistic Locking):假设并发操作时不会发生冲突,只有在提交事务时检查数据是否被其他事务修改过。常用于读多写少的场景。

  2. 悲观锁(Pessimistic Locking):假设并发操作时会发生冲突,因此在操作期间持有锁来避免冲突。常用于读少写多的场景。

  3. 全局锁(Global Locking):对整个数据库实例进行加锁,限制除超级用户外的所有查询和修改操作。一般用于备份、恢复等操作。

  4. 表级锁(Table Locking):对整个表加锁,其他连接无法修改或读取该表的数据,但可以对其他表进行操作。

  5. 页级锁(Page Lock):对数据页(通常是连续的几个行)加锁,控制并发事务对该页的访问。适用于数据较大且并发量较高的场景。

  6. 行级锁(Row Lock):对单个行加锁,只锁定需要修改的数据行,其他行可以被同时修改或读取。并发性高,但锁管理较复杂。

  7. 共享锁(Shared Lock):也称为读锁,多个事务可以同时持有共享锁并读取数据,但不能修改数据。适用于同时读取同一数据的场景。

  8. 排它锁(Exclusive Lock):也称为写锁,事务持有排它锁时,其他事务无法同时持有共享锁或排它锁,用于保护数据的写操作。

  9. 意向共享锁(Intention Shared Lock):表级锁的辅助锁,表示事务要在某个表或页级锁上获取共享锁。

  10. 意向排它锁(Intention Exclusive Lock):表级锁的辅助锁,表示事务要在某个表或页级锁上获取排它锁。

  11. 间隙锁(Gap Lock):锁定一个范围的键,但不包括这些键的实际值。用于防止其他事务在范围内插入数据。

  12. 临建锁(next-key Lock):Next-key锁是记录锁和间隙锁的组合,它指的是加在某条记录以及这条记录前面间隙上的锁。

  13. 记录锁(Record Lock):行级锁的特定类型,锁定单个行,确保其他事务无法同时修改或读取该行。

这些锁类型在不同的场景中可以组合使用,根据具体需求选择适当的锁策略来保证数据的一致性和并发性。同时,需要注意锁的粒度、锁冲突、死锁等问题,合理设计和管理锁可以提高数据库的并发性能。

行级锁加锁规则

对记录加锁时,加锁的基本单位是 next-key lock,它是由记录锁和间隙锁组合而成的,next-key lock 是前开后闭区间,而间隙锁是前开后开区间

但是,next-key lock 在一些场景下会退化成记录锁或间隙锁。

  1. 原则一:加锁的基本单位为next-key lock且范围为前开后闭。
  2. 原则二:查找过程中只有访问到的对象才会加锁,例如走全表扫描的情况,这种在扫描前就会给全表加上next-key lock。
  3. 优化一:索引上的等值查询,在给唯一索引加锁时,next-key lock会退化为行锁,因为主键是唯一的。
  4. 优化二:索引上的等值查询, 继续向右遍历时且最后一个值不满足等值条件的时候,next-key lock 退化为间隙锁。
  5. 一个bug: 唯一索引上的范围查询会访问到不满足条件的第一个值为止。

规则
唯一索引等值查询:

非唯一索引等值查询:

非唯一索引和主键索引的范围查询的加锁规则不同之处在于: