• penbox
    2023-07-12 来自四川
    《乐观锁与悲观锁》部分是不是有个BUG? “悲观锁是指在写入数据时直接加锁”,我觉得应该是“悲观锁是指在获取数据时直接加锁”

    作者回复: 可能是我这里因为要突出和上一条乐观锁的对比,让你产生了误解。应该是,悲观锁不管读写都要直接加锁。

    
    3
  • 子休
    2023-07-19 来自上海
    研究过一段时间锁的机制。举几个点,来分享一下如何理解临键锁。 首先这个名词“临键”非常拗口难记,但是大家仔细观察它的英文“next-key lock”,就可以发现一些名堂,我个人认为,所谓next-key的意思就是下一个索引的意思,也就是锁住查询结果中的最大索引值与下一个索引值之间的区域。这就意味着,临键锁锁住的最后的那个区间,是当前命中的索引最大值到下一个索引的区间,如果没有下一个索引,那就是锁住了剩下所有区间。结合本文的例子,大家就容易理解了。 例子1:如果 id 只有(1,4,7)三条记录,你查的是where id = 3,虽然没有查到记录,但是由于innodb中RR级别会使用临键锁,于是临键锁要开始锁区间了,但是锁哪里呢?这时候就要理解“临键”了,就是“next-key”,那么"next-key"是谁呢,根据查询条件ID=3,那么3后面的下一个索引是几呢?是4!! 那么临键锁就将(1,4]锁住了。 另外要额外提一句,由于查询条件可能是区间查询,所以临键锁会锁住多个区间。 比如查询条件 id>1 and id <6 它就会把(1, 4],(4,7]这两个区间都锁住。 又比如查询条件是id >1 and id<9 它就会把(1, 4],(4,7],(7, +∞]这三个区间都锁住,换句话说,这种查询也就导致了你根本插入不了任何一条记录,因为它把 id从1到无穷的范围都给锁住了。 为什么要锁住区间?因为要防止幻读出现(幻读就是同一事务里面,同一个sql查询查出来的记录行数不一样。为什么会不一样?因为有别的事务在你执行sql的时候进行了插入,插入到了你的查询条件范围内了,导致你上一次查还好好的,下一次查就莫名奇妙多出来记录了。)。 所以,你想,临键锁把你查询条件范围的区间锁住了,其它事务想往区间里面插数据是不是就不行了?临键锁是根据你的查询条件来锁区间的,这样你在同一事务里反复执行同一条sql查询,是不是就不会出现幻读了。 以上是个人浅见,欢迎指正。
    展开

    作者回复: 赞!我也无力吐槽临键锁这个翻译,但是大家都用我也跟着用。

    
    1
  • humor
    2023-07-12 来自浙江
    举个例子,如果数据库中只有 id 为(1,4,7)的三条记录,也就是 id= 3 这个条件没有命中任何数据,那么这条语句会加上间隙锁,而且是在 (-∞,1)、(1,4)、(7,+∞) 这些地方都加上间隙锁。所以你可以看到,在生产环境里面遇到了未命中索引的情况,对性能影响极大。 这个查询只会扫描到记录1和4吧,为什么7以后也加了间隙锁呢

    作者回复: 写错了,我修正一下!感谢指正!

    共 2 条评论
    1
  • rrbbt
    2023-07-12 来自山东
    之前写代码,事物里面,select语句从来不在后面加for update结尾。这样会有什么问题吗?

    作者回复: 如果你不加 for update 的话,正常来说是根据隔离级别,用 MVCC 的机制来读取数据。

    共 2 条评论
    1
  • Jason Ding
    2023-09-04 来自上海
    Next-Key Locks 没有完全解决幻读问题

    作者回复: 又是怎么个说法? To prevent phantoms, InnoDB uses an algorithm called next-key locking that combines index-row locking with gap locking. https://dev.mysql.com/doc/refman/8.0/en/innodb-next-key-locking.html

    共 2 条评论
    
  • Geek8004
    2023-09-03 来自中国香港
    意向共享锁和MDL读锁 ; 意向拍他锁和mdl写锁什么关系,等价吗?

    作者回复: 不是。意向锁的意思是我将来要拿一个锁,MDL 是你已经拿到了锁。所以我的理解就是,如果你要拿MDL 读锁,你现有一个意向共享锁。写锁也是类似的。

    
    
  • 牙小木
    2023-08-10 来自北京
    哈哈,实在又实用,

    作者回复: 谢谢!

    
    
  • 牙小木
    2023-08-10 来自北京
    提个醒:查询的索引含有唯一属性的时候,Next-Key Lock 会进行优化,将其降级为Record Lock,即仅锁住索引本身,但是普通索引没有唯一属性,就会升级为gap了

    作者回复: 是的。不过其实我觉得与其理解为优化,不如说如果我是一个设计者,我也会直接咔嚓一个记录锁锁住,因为在这种情况下我能准确推断出来哪些需要被锁住。

    
    
  • Geek_9af983
    2023-07-30 来自北京
    老师宁好呀,什么情况下select .... 需要加for update呀,我们项目中从来没这么写过

    作者回复: 你需要显式锁住某一行,不想别人修改的时候。你们不用说明你们可能用了乐观锁、分布式锁之类的东西。 不用是好事,哈哈哈。

    
    
  • 胡月🌈
    2023-07-28 来自北京
    我做过的项目隔离级别都是读已提交。可重复读隔离级别没用到过,有什么场景必须用可重复读吗?

    作者回复: 问倒我了,我自己没有遇到过。我认为在互联网业务里面应该没啥必须得场景,但是金融那边就不太确定。

    共 2 条评论
    