• 张学磊
    2019-08-13
    MySQL默认开启了死锁检测机制,当检测到死锁后会选择一个最小(锁定资源最少得事务)的事务进行回滚

    作者回复: 这个回答是我想要的。

    Innodb提供了wait-for graph算法来主动进行死锁检测,我们可以通过innodb_deadlock_detect = on 打开死锁检测。

    
     16
  • ok
    2019-08-16
    老师,请问事例中insert order_record的事务AB中,请解答下疑惑,我描述如下
    1、事务A执行select 4 for update获取(4,+∞)间隙锁
    2、图中B事务再执行select 5 for update获取(5,+∞)的间隙锁
    3、事务A执行insert 4 发现事务A自己持有(4,+∞)间隙锁,所以不用等待呀!
    4、事务B执行insert 5 发现事务A没有commit,持有(4,+∞)间隙锁,所以等待事务A释放锁
    5、事务A提交,事务B insert 5获取到锁,commit

    请指出问题…
    展开

    作者回复: 在3的insert操作中,回去获取插入意向锁,而插入意向锁也是一种gap锁,根据矩阵图,插入意向锁和gap间隙锁是冲突的,所以insert操作需要等待间隙锁的释放。

     2
     2
  • 我已经设置了昵称
    2019-08-13
    老师。我们一般不会在查询的时候加上for update,我们的组长让我们事务中不要放查询语句,只能放插入或者更新,就是提前查好,组装好,然后开始执行事务。我觉得这其实会出现重复插入(并发量一高就会出现)。请问老师事务中真的不能做查询操作吗,还有查询的时候怎么防止同时两个事务查不到相对应的数据而造成重复插入

    作者回复: for update是一种悲观锁实现,我们可以使用性能更好的乐观锁来实现,通过版本号来实现数据更新不丢失问题,这种方式是最佳选择。

    而对于插入时防重复问题,可以对不允许重复字段设置唯一索引,进行唯一约束,这是一种不友好的实现方式。

    
     2
  • a、
    2019-08-13
    1.设置Transaction的超时时间
    2.设置Transaction的级别为串行化级别
    
     2
  • 阿杜
    2020-01-10
    老师,有两个人闻到这个问题,感觉回答的我也不是很明白:
    1:老师你最后放的那张图,为啥主健索引还需要获取非主键索引的锁啊,主键索引不是已经持有这一整行数据了么?
    2.老师,您最后的那个例子,更新status时要获取index_order_status非聚簇索引,这句话能稍微解释一下吗?谢谢了
    麻烦老师详细解答下。
    
    
  • insist
    2019-12-26
    事务 A 和事务 B 都持有间隙 (4,+∞)的 gap 锁,而接下来的插入操作为了获取到插入意向锁,都在等待对方事务的 gap 锁释放,于是就造成了循环等待,导致死锁
    ------------------
    老师,请问一下,1、为什么A、B可以同时持有gap锁呢?2、为什么获取意向锁之前需要等待对方的gap锁呢? 比较迷茫

    作者回复: 由于 order_no 列为非唯一索引,此时又是 RR 事务隔离级别,所以事务A的select获取的是gap锁,事务B也是获取的gap锁,gap锁是相互兼容的,所以可以同时获取到。

    是为了防止幻读,需要通过插入意向锁实现阻塞等待gap锁的释放。

    
    
  • 孫やさん
    2019-12-25
    老师,您最后的那个例子,更新status时要获取index_order_status非聚簇索引,这句话能稍微解释一下吗?谢谢了

    作者回复: 在更新status时,由于是根据条件order_no来更新状态的,所以获取的是index_order_status索引,index_order_status是一个联合索引,由于不是主键,所以是非聚簇索引。

     1
    
  • neohope
    2019-11-26
    oracle里面的自增列,一般是通过一个sequence来控制的,一直感觉不如mysql方便。根据今天的例子来看,虽然sequence会产生一些不连续的情况,但好像可以减少一些脏读和死锁的情况,反而感觉挺合理的。
    
    
  • cky.宇
    2019-11-17
    感觉还可以把隔离级别改成RC。RR下锁比较严格,举两个例子:一个就是间隙锁的原因,就像老师的例子一样,如果一个事务在表t1 insert后没有commit,其他事务就不能对表t1进行insert,这样就可能会出现用户A的insert锁住了用户B的insert的情况,其实用户A和B是业务不相关的。而RC下没有间隙锁,不会有这种情况。 第二个就是RR加锁的范围更大,RR下会锁住所有扫描过的行,只有commit后才会全部释放,例如:select no from orders where status = 1 and create_at > xx for update; 其中只有status有索引,那么mysql就要先扫描status索引再回表找满足create_at的行。如果是RR下,会锁住所有status=1的行,直到commit后释放。如果是RC下,当找到满足条件(status, craeted_at)的行后,会释放掉不满住条件但是status=1的行,不需要等到commit。这些细节都会造成RC和RR的性能差距很大。而一些需要重复读的需求可以通过代码来保证。
    展开
    
    
  • 月迷津渡
    2019-10-21
    一个表它的主键是UUID生成的,如果说为了避免幻读而加了一个Next-key lock,那它会怎么锁的,感觉后插入的位置待定。。。还是全表锁?

    作者回复: 因为主键是唯一索引,所以不会使用next-key lock

    
    
  • ~
    2019-10-13
    老师, 我实践了一下, 发现select col from t where t.col = 'xx' for update会导致覆盖索引失效,而使用使用共享锁就不会失效, 这是什么原理呢

    作者回复: select col from t where t.col = 'xx' for update不会导致索引失效的,使用排他锁是不是发生了死锁了呢?

    
    
  • lizhibo
    2019-10-04
    老师 ,最后那个 根据主键ID 和 订单编号更新状态的例子 我这边怎么都是 锁等待 而没有出现死锁的情况, 事物级别RR

    作者回复: 互相锁等待,又无法释放彼此等待的锁,就是死锁状态了

     1
    
  • Demon.Lee
    2019-09-17
    感悟:
    1、默认将mysql隔离级别调成RC
    2、使用主键更新

    疑问:RR级别下,如果使用唯一索引更新,是record lock么?

    作者回复: 是的

    
    
  • man1s
    2019-09-16
    死锁检测,消耗cpu
    
    
  • godtrue
    2019-09-15
    课后思考及问题
    1:有个疑问,文中说“插入意向锁其实也是一种 gap 锁,它与 gap lock 是冲突的,所以当其它事务持有该间隙的 gap lock 时,需要等待其它事务释放 gap lock 之后,才能获取到插入意向锁。”
    在锁的兼容矩阵图中,先获取到Next-key lock再请求获取Insert Intention lock时是冲突的,反过来就是兼容的?

    作者回复: 一样是不兼容的

    
    
  • 💢 星星💢
    2019-09-10
    老师你最后放的那张图,为啥主健索引还需要获取非主键索引的锁啊,主键索引不是已经持有这一整行数据了么?

    作者回复: 索引和数据是两个概念,我们说过,聚合索引的叶子节点会存放整个数据,而辅助索引的叶子节点存放的是主键id

     1
    
  • 十大杰出青年
    2019-08-31
    老师,RC隔离级别下的select、update、delete基于聚簇索引和辅助索引分别获取什么lock?

    作者回复: 由于RC隔离级别只解决了脏读,所以是记录锁

    
    
  • 新世界
    2019-08-18
    for update和update都是悲观锁有什么区别?
    
    
  • K
    2019-08-18
    老师您好,麻烦问一下:“如果使用辅助索引来更新数据库,就需要使用聚簇索引来更新数据库...”这句话是什么意思啊?

    作者回复: 如果我们之前使用辅助索引来更新数据库,就需要修改为使用聚簇索引来更新数据库。

    
    
  • 星星滴蓝天
    2019-08-17
    我们有一个很悲催的经历,更新的时候没有使用主键更新,之前还好好的,后来(服务迁移、降低配置......处理流程变长)很悲剧的死锁了。

    作者回复: 过来人👍🏻

    
    
我们在线,来聊聊吧