死锁

死锁的介绍

  • 多个并发事务(2个或者以上);
  • 每个事务都持有锁(或者是已经在等待锁);
  • 每个事务都需要再继续持有锁;
  • 事务之间产生加锁的循环等待,形成死锁。

演示案例

  1. -- 事务A执行
  2. BEGIN;
  3. UPDATE users SET lastUpdate = NOW() WHERE id =1;
  4. UPDATE t2 SET `name`='test' WHERE id =1;
  5. ROLLBACK;
  6. -- 事务B执行
  7. BEGIN;
  8. UPDATE t2 SET `name`='test' WHERE id =1;
  9. UPDATE users SET lastUpdate = NOW() WHERE id =1;
  10. ROLLBACK;

image.png

事务A和事务B按照上面的执行步骤,最后因为存在相互等待的情况,所以 MySQL 判断出现死锁了。

死锁的避免

  • 类似的业务逻辑以固定的顺序访问表和行。
  • 大事务拆小。大事务更倾向于死锁,如果业务允许,将大事务拆小。
  • 在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁概率。
  • 降低隔离级别,如果业务允许,将隔离级别调低也是较好的选择
  • 为表添加合理的索引。可以看到如果不走索引将会为表的每一行记录添加上锁(或者说是表锁)

    作者:殷建卫 链接:https://www.yuque.com/yinjianwei/vyrvkf/dluggd 来源:殷建卫 - 架构笔记 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。