死锁是指两个或两个以上事务在执行过程中,因争夺资源而造成的一种互相等待的现象。若无外力作用,事务都将无法推进下去。
死锁的四个必要条件:

  1. 互斥条件:一个资源每次只能被一个进程使用。
  2. 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
  3. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
  4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

目前解决事务死锁主要有两种方式,超时回滚机制wait-for graph机制
超时机制:当两个事务互相等待时,当一个等待时间超过设置的某一阈值,其中一个事务进行回滚,另一个等待的事务就能继续执行。
wait-for graph(等待图)机制:wait-for graph要求数据库保存两种信息:锁的信息链表和事务等待链表。通过这两个链表可以构造出一张图,如果这个图中存在回路,就表示存在死锁。在每个事务请求锁并发生等待时都会判断是否存在回路,若存在则有死锁,通常来说InnoDB会选择回滚undo量最小的事务。
InnoDB存储引擎采用wait-for graph的方式来处理死锁。wait-for graph的死锁检测采用深度优先的算法实现。

🌰
image.png

其他

参考

《MySQL技术内幕:InnoDB存储引擎》