间隙锁和行锁加锁规则

作者&投稿:滕华 (若有异议请与网页底部的电邮联系)
~ 表和数据

规则总结(这个规则只限于截止到现在的最新版本,即 5.x 系列 <=5.7.24,8.0 系列 <=8.0.13。):
原则 1:加锁的基本单位是 next-key lock。希望你还记得,next-key lock 是前开后闭区间。
原则 2:查找过程中访问到的对象才会加锁。
优化 1:索引上的等值查询,给唯一索引加锁的时候,next-key lock 退化为行锁。
优化 2:索引上的等值查询,向右遍历时且最后一个值不满足等值条件的时候,next-key lock 退化为间隙锁。
一个 bug:唯一索引上的范围查询会访问到不满足条件的第一个值为止。

案例一:等值查询间隙锁

案例二:非唯一索引等值锁

根据原则1,优化2,锁的范围是(0,5],(5,10),但是根据原则2,只有访问到的对象才加锁,这个查询使用了覆盖索引,并不访问主键索引,所以主键上没加锁。
需要注意,在这个例子中,lock in share mode 只锁覆盖索引,但是如果是 for update 就不一样了。 执行 for update 时,系统会认为你接下来要更新数据,因此会顺便给主键索引上满足条件的行加上行锁。

案例三:主键索引范围锁

案例四:非唯一索引范围锁

这次 session A 用字段 c 来判断,加锁规则跟案例三唯一的不同是:在第一次用 c=10 定位记录的时候,索引 c 上加了 (5,10] 这个 next-key lock 后,由于索引 c 是非唯一索引,没有优化规则,也就是说不会蜕变为行锁,因此最终 sesion A 加的锁是,索引 c 上的 (5,10] 和 (10,15] 这两个 next-key lock。

案例五:唯一索引范围锁 bug

案例六:非唯一索引上存在"等值"的例子
表中插入一条mysql> insert into t values(30,10,30);

这时,session A 在遍历的时候,先访问第一个 c=10 的记录。同样地,根据原则 1,这里加的是 (c=5,id=5) 到 (c=10,id=10) 这个 next-key lock。
然后,session A 向右查找,直到碰到 (c=15,id=15) 这一行,循环才结束。根据优化 2,这是一个等值查询,向右查找到了不满足条件的行,所以会退化成 (c=10,id=10) 到 (c=15,id=15) 的间隙锁。

案例七:limit 语句加锁

索引 c 上的加锁范围变成了从(c=5,id=5) 到(c=10,id=30) 这个前开后闭区间,如下图所示:

案例八:一个死锁的例子

在读提交情况下,语句执行过程中加上的行锁,在语句执行完成后,就要把“不满足条件的行”上的行锁直接释放了,不需要等到事务提交。

费解的问题

1.由于是 order by c desc,第一个要定位的是索引 c 上“最右边的”c=20 的行,所以会加上间隙锁 (20,25) 和 next-key lock (15,20]。
2.在索引 c 上向左遍历,要扫描到 c=10 才停下来,所以 next-key lock 会加到 (5,10],这正是阻塞 session B 的 insert 语句的原因。
3.在扫描过程中,c=20、c=15、c=10 这三行都存在值,由于是 select *,所以会在主键 id 上加三个行锁。

参考: https://time.geekbang.org/column/article/75659


如何更改mysql事务隔离级别
InnoDB 通过加锁的策略来支持这些隔离级别。 行锁包含: Record Locks 索引记录锁,索引记录锁始终锁定索引记录,即使表中未定义索引, 这种情况下,InnoDB 创建一个隐藏的聚簇索引,并使用该索引进行记录锁定。 Gap Locks 间隙锁是索引记录之间的间隙上的锁,或者对第一条记录之前或者最后一条记录之后的锁。 间隙锁是...

卷帘门加锁
忘记开锁的情况下,提升卷帘会造成什么后果?会造成门片脱节掉落进滑道。增加锁控就要先增加加锁后断电,遥控器无动作,开锁后电机加电遥控器起作用。锁的图片没看明白,但图片内钥匙与锁比例太小应该安装不上门片厚度1厘米与滑道间隙一厘米,锁舌长度应在三厘米以上。建议:使用普通单片卷帘门门锁中的...

正确理解MYSQL的幻读
2、在RC模式下,使用当前读以及 [ UPDATE ]和 [ DELETE ]语句会对数据记录加行锁,但是不会加范围锁,间隙锁定仅用于外键约束检查和重复键检查。3、由于禁用了间隙锁定,因此可能会产生幻影行问题,因为其他会话可以在间隙中插入新行。4、 对于[ UPDATE ]或 [ DELETE ]语句, InnoDB 仅对其更...

打印时违反唯一约束条件
唯一约束指定表中某一列或多个列不能有相同的两行或者两行以上的数据存在,和主键约束不同,唯一约束允许为NULL,只是只能有一行。 InnoDB主要通过锁机制来实现主键约束和唯一约束,锁类型包括表锁和行锁,而行锁还细分为记录锁(RK)、间隙锁(GK)、插入意向锁(IK)、Next-Key(NK)等更细的子类型,...

mysql innodb和myisam区别
3、锁 mysql支持三种锁定级别,行级、页级、表级; MyISAM支持表级锁定,提供与 Oracle 类型一致的不加锁读取(non-locking read in SELECTs) InnoDB支持行级锁,InnoDB表的行锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表,注意间隙锁的影响 例如update table set num=...

开房间门锁
有硬卡片是可以的,不过要看你门隙的大小,如果可以整张卡片穿过门隙就一定能开!把卡片先穿透门隙,从底向上拉,到锁舌那就前后拉卡片,一次不行就多度一次!

java程序中如何实现对mysql数据库中表的锁定
在同一会话中加上了共享锁.可以对这个表以及这个表以外的所有表进行增、删、改、查的操作.在不同的会话中.可以查到共享锁锁住行的最新消息.但是在Read Uncommitted隔离级别下不能对锁住的表进行删,改操作.(需要等待锁释放才能操作...)在Read Committed隔离级别下不能对锁住的表进行删,改操作.(...

mysql 死锁可以自动解除吗
察看死锁 select sess.sid,sess.serial#,lo.oracle_username,lo.os_user_name,ao.object_name,lo.locked_mode from v$locked_object lo,dba_objects ao,v$session sess where ao.object_id = lo.object_id and lo.session_id = sess.sid order by ao.object_name ;清除死锁 alter system kill...

半月板损伤恢复时间
破裂的半月板如部分滑入关节之间,使关节活动发生机械障碍,妨碍关节伸屈活动,形成“交锁”。在严重创伤病例,半月板,十字韧带和侧副韧带可同时损伤。半月板损伤的部位可发生在半月板的前角、后角、中部或边缘部。损伤的形状可为横裂、纵裂、水平裂或不规则形,甚至破碎成关节内游离体。病理特点:半月板的外缘较厚,与...

多雨日雨刮器保养原则大透析
雨刮虽然搁在挡风玻璃上,但日常保养时人们却很容易视而不见,等用上了才知道有问题。雨刮片的保养方法其实很简单。每次洗车时除了洗净玻璃窗,最好也用玻璃清洗液擦拭雨刮条,这样雨刮条的寿命就会长一些。如果由洗车店代劳清洁,可以提醒一下店员为你做这项工作,将雨刮开关置于各种速度位置处,检查不同速度下雨刮...

泉港区13649975929: mysql数据库的锁有多少种,怎么编写加锁的sql -
宇肺熊胆: 1.度娘搜mysql to sql server 2008,有比较容易使用的工具,推荐2.数据库传给我我帮你转,限免费一次

泉港区13649975929: sysbase数据库,行锁,页锁,全页锁定的区别,加锁有什么作用?萌新,请大佬们用通俗的话解答一下 -
宇肺熊胆: 1、全页锁(allpages lock) 对查询的表及索引页加锁,也就是table lock 2、页锁 (data lock) 对所查询的结果所在页加锁,对索引不加锁 3、行锁 (row lock) 对某行数据加锁 好像一个lock占用的内存为120byte! 锁只是一种保护机制,并不影响数据存储!

泉港区13649975929: mysql中innodb引擎的行锁是通过加在什么上完成的 -
宇肺熊胆: 加载索引上,

泉港区13649975929: sqlserver怎么实现一个行锁 -
宇肺熊胆: 1 如何锁一个表的某一行SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED SELECT * FROM table ROWLOCK WHERE id = 12 锁定数据库的一个表SELECT * FROM table WITH (HOLDLOCK)加锁语句: sybase: update 表 set...

泉港区13649975929: SQL SERVER 中如何使用行锁? -
宇肺熊胆: 给你个最详细的吧 可能有你要的内容 锁的概述 一. 为什么要引入锁 多个用户同时对数据库的并发操作时会带来以下数据不一致的问题: 丢失更新 A,B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏了另一个修改的结果,比如订...

泉港区13649975929: java如何给数据库加行锁 -
宇肺熊胆: 与java无关,要用sql语句实现 前提目标表要有索引,查询要开启事物,使用select * from tb with(updlock) where col = xxx将一行数据锁住,其他连接不能再修改表

泉港区13649975929: mysql数据库的行级锁有几种 -
宇肺熊胆: 有两种模式的行锁:1)共享锁:允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁. ( Select * from table_name where ......lock in share mode)2)排他锁:允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和 排他写锁.(select * from table_name where.....for update)

泉港区13649975929: 悲观锁 乐观锁 行锁/表锁/页锁 排他锁(独占锁)/更新锁/共享锁 麻烦高手帮忙屡屡 非常感谢 -
宇肺熊胆: 悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁.传统的关系型数据库里边就用到了很多这种锁机制,比如行锁...

泉港区13649975929: 怎样写sql语句可以加上行级排它锁 -
宇肺熊胆: 看你需要加哪种类型的锁:HOLDLOCK 将共享锁保留到事务完成,而不是在相应的表、行或数据页不再需要时就立即释放锁.HOLDLOCK 等同于 SERIALIZABLE.NOLOCK 不要发出共享锁,并且不要提供排它锁.当此选项生效时,可能会...

泉港区13649975929: mysql锁算法的底层实现? -
宇肺熊胆: Record Lock: 单个行记录上的锁Gap Lock :间隙锁,锁定一个范围,但不包含记录本身Next-Key Lock:Gap Lock + Record Lock,锁定一个范围,并且包含记录本身Record Lock会锁住索引记录,如果建表时没有设置添加索引,Innodb会去锁定隐式的主键.

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网