【mysql】记录锁、间隙锁与临键锁

本文详细介绍了MySQL 8.0.29中记录锁、间隙锁和临键锁的概念及作用。记录锁在存在唯一索引时为行锁,否则变为间隙锁;间隙锁防止其他事务在锁定的间隙内插入记录;临键锁结合了记录锁与间隙锁,用于解决幻读问题。在不同隔离级别下,锁的行为有所不同。
摘要由CSDN通过智能技术生成

结论(mysql版本8.0.29)

操作的字段建有唯一索引

  1. 记录锁对应记录存在时,为行锁不存在时,为间隙锁
  2. 加锁范围两端值存在记录时,仅锁住范围内间隙;某端值不存在或者都不存在时,取端值所在间隙加锁;

操作的字段仅有非唯一索引

  1. 记录锁对应记录存在时,为临键锁不存在时,为间隙锁
  2. 加锁范围两端值存在与否都取其所在间隙加锁;

: mysql 版本的不同,在以上的处理上有所差异;但是相同点在于均区分是否建有唯一索引

记录锁(Record Locks)

A record lock is a lock on an index record.

作用:阻止其他事务插入/删除/更新该记录
使用示例

SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE;  
/* 此处假定c1列建了唯一索引,故仅锁住该行 ,注意与下面的Next-key Locks区分 */   

:

  1. 记录锁仅作用在索引上,如果没有索引,InnoDB 会创建一个隐藏的聚集索引,然后使用记录锁
  2. 如果加锁的记录存在,则对该记录加锁;如果该记录不存在,变成间隙锁;(mysql 版本8.0.29)

间隙锁(Gap Locks)

A gap lock is a lock on a gap between index records, or a lock on the gap before the first or after the last index record

作用:阻止其他事务插入该间隙的记录(即使该记录不存在)
使用示例

SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;

  1. 一般情况下,使用唯一索引的查询条件没有间隙锁,如果c1建有唯一索引?仅锁住区间内的记录(包含不存在的),如果是间隙锁,则与前部分声明相悖,如果是记录锁,那么幻读问题得不到解决,所以此处更像是一种区间锁(此处实际上的处理看mysql版本);特殊情况,唯一索引包含多列,且查询条件仅包含其中的某些列,也会产生间隙锁
  2. 如果c1 建有唯一索引,且查询范围两端值存在记录,则只锁住范围内的间隙,即[10,20] (mysql版本8.0.29,旧版本统一处理成间隙锁); 如果某端值不存在,则对其所在间隙加锁;
  3. 如果设置隔离级别为读已提交(默认是可重复读),扫描索引时不会加间隙锁,完整性检查时才加锁

临键锁(Next-Key Locks)

A next-key lock is a combination of a record lock on the index record and a gap lock on the gap before the index record

作用:记录锁与间隙锁的作用集合
使用实例

SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE;  
/* 此处假定c1列没有唯一索引,此处锁住该行以及之前的间隙,如果该记录不存在-->间隙锁;注意与上面的Record Locks区分 */   

:默认情况下,InnoDB 事务隔离级别(版本8.0.29)为可重复读(REPEATABLE READ),扫描索引时使用临键锁,解决幻读问题(phantom rows)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值