栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Mysql 间隙锁,next-key的原理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Mysql 间隙锁,next-key的原理

mysql的间隙锁原理 首先明确一个大前提  就是主键索引 和唯一索引是锁的当前行   而间隙锁锁定的是 索引字段 靠近左边的第一个值+1  以及靠近右边的第一个字段-1  所以 间隙锁 在很多的情况下 差不多就是行锁 可以这么主观的认为 然后还要明确一个大前提  会对什么加锁   首先where条件中的字段进行加锁   insert会加锁 看这个id是否被间隙锁给锁住。    然后还有一个地方 对于set的字段会查看要set成的值 是否被锁定。很神奇(下面找一个场景来介绍) 在还有一点就是  不同的就是  两个where条件的索引 是不互相印象的  除非命中了同一行 因为innodb会在间隙锁的基础上 加上行锁行程next-key lock; 有这么一张表数据为下图   shippingPlan 和 orderStatus 都是独立的索引 id 为主键索引

 

首先来看一个next-key lock的例子 Set autoCommit = 0; update furniture_oms__shipping_plan_line_b_o set buyerName = '231' where shippingPlan = 18 这时候的锁定范围为 shippingPlan    >16   锁定范围   <19     id   >12 锁定范围  < 18  没错id也会属于锁定范围 这时候我们执行 update furniture_oms__shipping_plan_line_b_o set buyerName = '231' where id = 15 这条语句不会被锁定  因为shippingPlan 和 id是两个不同的索引 所以互不影响   但是我们执行 insert into  furniture_oms__shipping_plan_line_b_o values(16, 100,’ dadadad’ ) 这时候会锁定  等待 上面的提交 或者执行 update furniture_oms__shipping_plan_line_b_o set id = 13 where shippingPlan = 24  或者执行 update furniture_oms__shipping_plan_line_b_o set id = 13 where orderStatus =  ‘wanqianhaoXiao' 或者执行 update furniture_oms__shipping_plan_line_b_o set shippingPlan = 17 where orderStatus =  ‘wanqianhaoXiao' 这几条语句都会锁定   其实可以看一下 当我们要更新某个字段的时候  也会判断这个字段对应的锁 是否在被锁定中  如果被锁定中 就不会更新  虽然他们的where条件各不相同   比如上面的语句 我们要将id更新为13  但是 12-18范围内的id都已经被锁定了  所以不允许更新  我们要将shippingPlan更新为17  但是16-19范围内的shippingPlan都已经被锁定了 所以也不允许更新。 其实如果你把mysql的隔离级别降为读已提交  你会发现下面的绝大多数的语句都能执行。 为什么 读已提交不行  我列举一个场景 我们知道读已提交的隔离级别 binlog同步的是sql语句  看一下下面的情况 Transactional1                                                                                       transactional2 Set autoCommit = 0                                                                      Set autoCommit = 0 Update table name = “dada” where shippingPlan = 13                                                                                                      Update table shippingPlan = 13 where id = 10000                                                                                                      Commit; Commit; 这时候主从同步的时候  从服务器 回放这两条sql语句的时候 因为是事物2先提交到  所以事物2先到 这时候 执行就会造成数据不一致。 总结 mysql的next-key lock 是锁定的一个范围和当前行   任何一个索引都会根据自己的索引锁定一个范围和id的一个范围。     索引之间是不冲突的 只要你不是都是更新同一行。 当你要吧某个值进行set的时候  也会判断你要set之后的值  是否已经被别的事物给锁定了 这时候不允许更新。 所以我们可以大胆的说一句  在很多场景下 间隙锁影响的是Insert  因为你不会经常更新索引字段吧。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/716500.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号