锁
• 行锁 Record Lock: 锁定具体行记录,依附于索引存在
• 间隙锁 Gap Lock: 针对行记录之间的空隙加锁
• 临键锁 Next-Key Lock: 本质上是间隙锁加行锁形成的组合
• 意向锁 Intention Lock: 在具体操作行为前进行意向声明
锁与索引
加锁锁住的其实是索引项,更加具体地来说,就是锁住了叶子节点。
一个表有很多索引,锁的是哪个索引呢?其实就是查询最终使用的那个索引。万一查询没有使用任何索引呢?那么锁住的就是整个表,也就是此时退化为表锁。
释放锁时机
只有在执行 Rollback 或者 Commit 的时候,锁才会被释放掉。
乐观锁
乐观锁是直到要修改数据的时候,才检测数据是否已经被别人修改过。悲观锁是在初始时刻就直接加锁保护好临界资源。
乐观锁适用于读多写少的场景,互联网中大部分应用都属于这一类。而悲观锁则适用于写多读少的场
景,比如在金融领域里面对金额的操作就是以写为主。
乐观锁的性能要比悲观锁好很多。不过因为乐观锁的代码写起来比较复杂,所以很多人偷懒就会直接使用悲观锁。
行锁和表锁
一般来说,行锁是指锁住行,可能是锁住一行,也可能是锁住多行。表锁则是直接将整个表都锁住。
行锁是借助索引来实现的,也就是说,如果你的查询没有命中任何的索引,那么 InnoDB 引擎是用不了行锁的,只能使用表锁。当然,如果用的是 MySQL,类似于 MyISAM 引擎,那么只能使用表锁,因为这些引擎不支持行锁。
共享锁和排他锁
类型 共享锁 排它锁
共享锁 兼容 不兼容
排它锁 不兼容 不兼容
共享锁:允许一个事务读取一行数据,但不允许一个事务对加了共享锁的当前行增加排他锁。排他锁:允许当前事务对数据行进行增删改查操作,不允许其他事务对增加了排他锁的数据行增加共享锁和排他锁。
页面锁- BerkeleyDB 存储引擎
页面锁
页级锁定是 MySQL 中比较独特的一种锁定级别。特点:锁定颗粒度介于行级锁定与表级锁之间,锁开销和加锁时间界于表锁和行锁之间,并发处理能力也同样是介于上面二者之间,并发度一般。
不过,随着锁定资源颗粒度的减小,应用程序的访问请求遇到锁等待的可能性也会随之降低,系统整体并发度也随之提升。
使用页级锁定的主要是 BerkeleyDB 存储引擎。
间隙锁
在mysql中使用范围查询的时,如果请求共享锁或者排他锁,InnoDB会给符合条件的已有数据的索引项加锁。如果键值在条件范围内,而这个范围内并不存在记录,而认为此时出现了间隙,InnoDB会对这个间隙进行加锁,这也称为间隙锁。
eg:
上面出现了间隙有 (3,7], (7,10], (10,21],(21,+∞] 的三个区间。
如果执行以下sql
那么其他事务就无法在 (7,21] 这个区间内插入或者修改任何数据。间隙锁会锁住 (7,10], (10,21] 这两个间隙。不过间隙锁只会在 可重复读事务隔离级别 下才会生效。
next-key lock临键锁
临键锁就是行锁和间隙锁的组合,也可以理解为一种特殊的间隙锁。通过临建锁可以解决幻读的问题。
每个数据行上的非唯一索引列上都会存在一把临键锁,当某个事务持有该数据行的临键锁时,会锁住一段左开右闭区间的数据 。
需要强调的一点是,InnoDB 中行级锁是基于索引实现的,临键锁只与非唯一索引列有关 ,在唯一索引列(包括主键列)上不存在临键锁。
什么是临键锁?
- 定义:临键锁是MySQL InnoDB存储引擎在可重复读(Repeatable Read, RR)隔离级别下为了解决幻读问题而引入的一种锁定机制。
- 含义:“Next-Key”可以理解为下一个索引值,临键锁锁定的是查询结果中的最大索引值与下一个索引值之间的区域。
如何工作?
- 当一个事务执行查询时,InnoDB会在查询结果集的基础上加锁,并且还会锁住可能影响该查询结果的下一个索引值之前的区域。
- 如果没有下一个索引值,则锁住查询条件之后的所有区域。
示例说明
- 查询单个不存在的记录:
- 假设表中
id
列仅有值1、4、7,查询WHERE id = 3
。 - 尽管没有找到记录,但锁定了从1到4的区间(即
[1, 4)
,注意这里不包含4)。
- 区间查询:
- 查询条件如
WHERE id > 1 AND id < 6
。 - 锁定的区间包括
[1, 4]
和(4, 7]
。 - 查询条件如
WHERE id > 1 AND id < 9
。 - 锁定的区间包括
[1, 4]
、(4, 7]
以及(7, +∞)
。
目的
- 防止幻读:通过锁定查询条件覆盖的区间,防止其他事务在此期间插入新的记录,从而避免在同一事务中执行相同的SQL语句时返回不同数量的结果行,这就是所谓的幻读现象。
- 临键锁机制确保了在RR隔离级别下,事务执行相同查询时的一致性,避免了幻读的发生。
- 在设计查询或考虑并发控制时,理解临键锁的工作原理有助于优化应用性能和数据库设计。
总结
资料
Loading...