mysql 间隙锁和临键锁原理

mysql 间隙锁和临键锁原理,第1张

以下面的表为例子进行说明

间隙锁的产生来自于 InnboDB 引擎在可重复读的级别基础上执行当前读时出现的幻读问题。下面来分析一下幻读的例子, 假如没有间隙锁的话 ,那么会出现下面的现象:

如上表如示,是基于没有间隙锁的假设,sessionA 事务内执行两次相同的当前读返回的数据不一样,出现幻读的现象。因为(2,2,10)这条记录在原本的数据并不存在,行锁就锁不住,因此诞生间隙锁。

首先看看sessionA的执行计划,发现用到覆盖索引

场景 1:插入到索引 a 时,要插入是索引是(11,5),属于(a=10,id=10)和(a=30,id=30)之间的锁范围,所以阻塞

场景 2、3、4 同理分析得出结论

本例子跟《查询条件走二级索引例子》区别在于 sessionA 是 select * ,因此需要回到主键索引查询所有字段,扫描了主键索引,所以也会在扫描到的索引进行加 next-key lock。该语句回表一次,扫描到是行是 id=10,所以加锁是(0,10],(10,20),因此 sessionA 一共加了锁是索引 a 的(10,30)和主键索引的(0,20)。

mysql 为并发事务同时对一条记录进行读写时,提出了两种解决方案:

1)使用 mvcc 的方法,实现多事务的并发读写,但是这种读只是“快照读”,一般读的是历史版本数据,还有一种是“当前读”,一般加锁实现“当前读”,或者 insert、update、delete 也是当前读。

2)使用加锁的方法,锁分为共享锁(读锁),排他锁(写锁)

快照读:就是select

当前读:特殊的读 *** 作,插入/更新/删除 *** 作,属于当前读,处理的都是当前的数据,需要加锁。

mysql 在 RR 级别怎么处理幻读的呢?一般来说,RR 级别通过 mvcc 机制,保证读到低于后面事务的数据。但是 select for update 不会触发 mvcc,它是当前读。如果后面事务插入数据并提交,那么在 RR 级别就会读到插入的数据。所以,mysql 使用 行锁 + gap 锁(简称 next-key 锁)来防止当前读的时候插入。

Gap Lock在InnoDB的唯一作用就是防止其他事务的插入 *** 作,以此防止幻读的发生。

Innodb自动使用间隙锁的条件:


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/7436841.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-05
下一篇 2023-04-05

发表评论

登录后才能评论

评论列表(0条)

保存