RR隔离级别下锁情况(探究gap锁和行锁)

!!!我的数据库演示版本为5.5,以后会追加最新数据库的演示版本

间隙锁(GAP Lock)时InnoDB在可重复读下的隔离级别下为了解决幻读问题引入的锁机制。幻读存在的问题是因为在新增或者更新时如果进行查询,会出现不一致的现象,这时单纯的使用行锁无法满足我们的需求,我们需要对一定范围的数据加锁,防止幻读。

可重复读隔离级别就是数据库通过行锁和间隙锁(不要搞混gap lock和next-key lock共同组成来实现的,在网上抄了一下加锁的规则,然后自己进行一下验证:

  • 1.加锁的基本单位是(next-key lock),遵循前开后闭原则,对于闭合的索引采用行锁,区间范围是间隙锁,间隙锁锁住的是insert操作,而行锁会锁住所有当前读操作
  • 2.插叙过程中访问的对象会增加锁
  • 3.索引上的等值查询-------给唯一索引加锁的时候,next-key lock会升级为行锁
  • 4.索引上的等值查询-------向右遍历时最后一个值不满足查询需求时,行级锁会退化为间隙
  • 5.唯一索引上的范围查询到不满足条件的第一个值为止(看不懂这条可以看下文中的主键索引+范围查询的情况3)

下图是演示数据库表(第一列是主键索引,第二个普通索引,第三个是没有索引,第四个是唯一索引)

以上数据为了解决幻读问题,更新时除了对该四条数据加行锁外,还会对他们的中间范围加锁分别为(无穷小,5] (5,10] (10,15] (15,20] (20,无穷大] 如上文规则1中所说都是遵循左开右闭原则的

其实主键索引和唯一索引最终的结果是相同的,区别就是对唯一索引加锁最终也会通过聚簇索引对主键索引加锁。

主键索引(唯一索引)+等值查询+条件命中

  1. 上图中左边事务执行查询主键索引为5的记录,且表中真实存在5,此时事务尚未提交,右边事务想要在主键索引为3的位置插入索引
  2. 规则1中介绍,加锁的基本单位是next-key lock,锁的范围是(无穷小,5]  但此时属于规则3中所说的"唯一索引上的等值查询"
  3. (无穷小,5] 的间隙锁升级为了行锁,只锁住了5这条索引记录,所以右侧事务可以正常执行insert操作。

主键索引(唯一索引)+等值查询+条件未命中

上图中左边事务查询主键索引为6的记录,且表中并不存在6,此时事务尚未提交,右边事务想要在主键索引为7的位置插入索引。规则1中介绍,加锁的基本规则是next-key lock,锁的范围是(5,10]  ,规则3中说唯一索引上的等值查询会升级为行锁,但是规则4中又介绍,条件未命中的索引会由行锁退化为间隙锁,此时锁的范围(5,10),右边事务阻塞。

上图可以看到主键索引为10的位置已经放锁了,说明next-key lock已经变为了间隙锁,放开了索引为10这个位置,进一步证明了此时为间隙锁,锁范围为(5,10)

主键索引(唯一索引)+范围查询

情况1.查询范围都在next-key lock的一个范围内

  1. 上图主键查询的范围是 4<=id_primary_key < 5根据
  2. 原则1在(1,5] 之间加入key-next lock,右边事务执行结果可以看出在主键索引为3的位置可以正常执行当前读操作但是不能执行insert操作,说明有间隙锁
  3. 在主键索引为5的位置不能执行当前读操作,说明有行锁。

情况2.查询范围在next-key lock的多个范围内(圆圈代表阻塞,对号代表未阻塞)

  1. 黑色图片部分代表了事务1,查询范围为5<=id_primary_key<10
  2. 此时由规则1,key-next lock包含的范围有(负无穷,5]  (5,10]
  3. 对比蓝色图片事务2中的1、3和5操作我们可以发现,(负无穷,5] 由于属于主键索引的等值查询已经升级到了行锁(主键索引5的位置当前读阻塞,但是主键索引为3的位置可以正常执行insert操作)
  4. (5,10] 部分依旧是key-next lock(主键索引为8的位置可以执行当前读操作,但是不能执行insert操作)。对于主键索引为10的位置处于行锁状态(因为这是key-next lock的闭合位置),忘了测了,但结论不会错

情况3.在情况2下多了一小点,用来介绍规则5

左边图片事务1执行了查询主键索引10<=id_primary_key<11的范围

根据规则1,此时会锁住(5,10]

根据规则5:唯一索引上的范围查询到不满足条件的第一个值为止

我们的查询范围中第一个不满足条件的位置当然是id_primary_key=11的这个位置,所以此时依旧会将(10,15] 范围锁住

根据情况2我们就可以知道(5,10] 的key-next lock已经升级到了行锁,所以此时的锁范围是 [10,15]

普通索引+等值查询+条件命中(未完待续)

在开始测试普通索引之前,先向表中增加一条数据

原文地址:https://www.cnblogs.com/leeeeemz/p/12587641.html

时间: 2024-08-01 05:39:55

RR隔离级别下锁情况(探究gap锁和行锁)的相关文章

Read Commited 隔离级别下锁情况(MVCC实现原理)

如何通过单纯加锁实现RC隔离级别的隔离效果? 对InnoDB引擎下的mysql数据库支持行级锁,通过对事务访问时增加排他锁(X锁)可以防止其他事务的访问,只有在该事务锁提交也就是commit后才可以访问,避免脏读产生.但是在多读的场景下,一个事务假如在进行update操作,后面有许多请求都想要单纯进行读操作(普通的SELECT语句),可是因为有锁的存在只能进行等待.该方法在多读的并发环境下效率大大降低. 真实情况下由于InnoDB在RC和RR隔离级别下使用了MVCC机制,实现了一致性非阻塞读,提

浅析SQL Server在可序列化隔离级别下,防止幻读的范围锁的锁定问题

原文:浅析SQL Server在可序列化隔离级别下,防止幻读的范围锁的锁定问题 本文出处:http://www.cnblogs.com/wy123/p/7501261.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错误进行修正或补充,无他) 数据库在处理并发事物的过程中,在不同的隔离级别下有不同的锁表现,在非可序列化隔离级别下,存在着脏读,不可重复读,丢失更新,幻读等情况.本文不讨论脏读和不可重复读以及丢失更新的情形,仅讨论幻读,幻

mysql 开发进阶篇系列 12 锁问题(隔离级别下锁的差异)

1. innodb在不同隔离级别下的一致性读及锁的差异 不同的隔离级别下,innodb处理sql 时采用的一致性读策略和需要的锁是不同的,同时,数据恢复和复制机制的特点,也对一些sql的一致性读策略和锁策略有很大影响.对于许多sql, 隔离级别越高,innodb给记录集的锁就越严格(龙其是使用范围条件的时候),产生的锁冲突的可能性也就越高,对并发性事务处理性能的影响也就越大.因此,在应用中,应该尽量使用较低的隔离级别,减少锁争用.通常使用Read Commited隔离级别就足够了, 对于一些确实

MySQL Transaction--RR事务隔离级别下加锁测试

============================================================================== 按照非索引列更新 在可重复读的事务隔离级别下,在非索引列上进行更新和删除会对所有数据行进行加锁,阻止其他会话对边进行任何数据的增删改操作. 如果更新或删除条件为c3=4且c3列上没有索引则: 1.不允许其他会话插入任意记录,因为所有记录的主键索引上存在X排他锁,无法申请插入意向X锁(lock_mode X insert intention

Transaction And Lock--READ COMMITTED隔离级别下的"脏读"

在READ UNCOMMITTED事务隔离级别下或使用WITH(NOLOCK)来查询数据时,会出现脏读情况,因此对于一些比较"关键"的业务,会要求不能使用WITH(NOLOCK)或允许在READ UNCOMMITTED事务隔离级别下,于是我们使用默认的READ COMMITTED隔离级别来访问数据,但是这样真的就没有问题么? 让我们来做个小实验 准备测试数据 --======================================= --创建测试表 CREATE TABLE T

浅谈mysql中不同事务隔离级别下数据的显示效果

事务的概念 事 务是一组原子性的SQL查询语句,也可以被看做一个工作单元.如果数据库引擎能够成功地对数据库应用所有的查询语句,它就会执行所有查询,如果任何一条查 询语句因为崩溃或其他原因而无法执行,那么所有的语句就都不会执行.也就是说,事务内的语句要么全部执行,要么一句也不执行. 事务的特性:acid,也称为事务的四个测试(原子性,一致性,隔离性,持久性) automicity:原子性,事务所引起的数据库操作,要么都完成,要么都不执行consisitency:一致性,事务执行前的总和和事务执行后

mysql中不同事务隔离级别下数据的显示效果--转载

事务是一组原子性的SQL查询语句,也可以被看做一个工作单元.如果数据库引擎能够成功地对数据库应用所有的查询语句,它就会执行所有查询,如果任何一条查询语句因为崩溃或其他原因而无法执行,那么所有的语句就都不会执行.也就是说,事务内的语句要么全部执行,要么一句也不执行. 事务的特性:acid,也称为事务的四个测试(原子性,一致性,隔离性,持久性) automicity:原子性,事务所引起的数据库操作,要么都完成,要么都不执行 consisitency:一致性,事务执行前的总和和事务执行后的总和是不变的

MySQL--REPEATABLE-READ隔离级别下读取到的“重复数据”

在MySQL中,使用MVCC来实现REPEATABLE-READ隔离级别,由于SELECT操作不会对数据加锁,其他回话可以修改当前回话所读取过的数据而不会被阻塞,因此读写不冲突. 在MVCC并发控制中,读操作可以分成两类:快照读 (snapshot read)与当前读 (current read).快照读,读取的是记录的可见版本 (有可能是历史版本),不用加锁.当前读,读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录.(抄自MySQL 加锁处理分析)

MySQL学习总结-演示不同隔离级别下的并发问题

演示不同隔离级别下的并发问题 1.当把事务的隔离级别设置为read uncommitted,会引发脏读.不可重复读和虚读A窗口set transaction isolation level read uncommitted;start transaction;select * from bank;----发现a账户是1000元,转到b窗口select * from bank; B窗口start transaction;update bank set money=money+100 where n