• mysql在update,非主键索引更新引起死锁


    1.mysql存储引擎:


    Innodb: 支持事务,更新时采用行级锁,并发性高
    MyISAM: 不支持事务,更新时表锁,并发性差
    因此使用Innodb才会发生死锁,从mysql5.6开始默认引擎Innodb

    2.update更新过程


    行级锁并不是直接锁记录,而是锁索引,如果一条SQL语句用到了主键索引,mysql会锁住主键索引;如果一条语句操作了非主键索引,mysql会先锁住非主键索引,再锁定主键索引。反之,
    如果操作用到了主键索引会先在主键索引上加锁,然后在其他索引上加锁。
    如果没有用到索引,则进行全表扫描,锁表。
    当where条件为非主键索引,执行update时,会经过一下步骤:
    1)先获取非主键索引的行级锁;
    2)由数据库基本原理可知,where条件为非主键索引时,会发生回表查询,进而再获得主键索引的行级锁;
    3)更新完毕,进行事务提交。

    根据上述步骤可知,对于非主键索引的update操作,其加锁过程并非原子操作,而且是分别需要获取不同索引的行级锁,可能会产生死锁:
    假如,一条update语句用到主键索引和非主键索引,则获取锁的顺序是先获取主键索引,再获取非主键索引;而同时,另一条update语句只用到非主键索引,则获取锁的顺序是先获取非主键索引,再获取主键索引,二者正好发生在步骤 1)和 2)中间,则会造成锁。

    3.解决方案


    where条件加主键索引
    先上锁查询查出来,在根据主键更新
    逐条更新

    行级锁是锁索引:

    由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的

  • 相关阅读:
    为何大佬喜欢用聚合当领域设计的基本单元
    【图与网络数学模型】3.Ford-Fulkerson算法求解网络最大流问题
    正则表达式的应用领域及基本语法解析
    Linux进程控制
    C# App.xaml.cs的一些操作
    面试高频手撕算法 - 背包问题2
    Vue 快速入门案例
    MYSQL中的锁
    开源与闭源:数字化时代的辩论与未来走向
    MySQL字符集
  • 原文地址:https://blog.csdn.net/susu1083018911/article/details/126645526