死锁是如何被发现和解决的?这篇文章告诉你

89 阅读3分钟

什么是死锁检测机制?

1. 什么是死锁?

先理解“死锁”。
想象一个场景:

  • 有两个人正在用电脑工作,一个人需要打印机,另一个人需要扫描仪。
  • 人A已经拿到了打印机,但正在等待扫描仪;而人B已经拿到了扫描仪,但正在等待打印机。
  • 结果就是:两个人互相等待,谁也无法继续工作

在数据库中,类似的情况也会发生:

  • 两个事务同时运行,一个事务锁住了某些资源,而另一个事务锁住了另一些资源。
  • 如果这两个事务相互依赖,形成了循环等待,就会导致谁也干不了活,这就是死锁

2. 死锁如何解决?

为了防止死锁影响系统运行,MySQL 等数据库提供了一种机制叫死锁检测机制。它会自动监控并解决死锁问题。


3. 死锁检测机制的原理

在数据库中,死锁检测机制就像一个“裁判”,它会定期检查事务的等待情况,当发现有 “循环等待”时,主动介入解决。

具体步骤如下:

  1. 事务运行时加锁
    每个事务在操作数据时,都会尝试获取锁(如行锁、表锁)。
  2. 检测是否发生死锁
    当一个事务进入等待状态时,系统会检查是否存在“循环等待链”(A 等 B,B 等 C,C 又等 A)。
  3. 发现死锁时选择牺牲者
    一旦检测到死锁,系统会自动终止其中一个事务(牺牲者),释放它占用的锁,解除死锁。
  4. 其他事务继续运行
    被终止的事务会回滚操作,其他事务正常继续。

4. 案例:死锁检测机制的作用

假设有两个事务:

  • 事务 A:锁住账号表 account_tbl 的某一行,然后想锁住订单表 order_tbl 的一行。
  • 事务 B:锁住订单表 order_tbl 的某一行,然后想锁住账号表 account_tbl 的一行。

如果没有死锁检测机制:

  • 两个事务都在等待对方释放锁,结果就是系统卡住,所有事务都无法继续运行

如果有死锁检测机制:

  • 数据库会发现事务 A 和 B 之间形成了循环等待(死锁)。
  • 系统会主动选择终止一个事务(比如事务 B),让事务 A 继续完成操作。
  • 事务 B 会收到一条错误信息(如 ERROR 1213: Deadlock found),提醒它需要重新尝试。

5. 死锁检测机制的优点

  • 自动化检测:系统可以自动发现并处理死锁,无需人工干预。
  • 快速恢复:通过牺牲一个事务,确保其他事务不受影响,避免系统卡死。
  • 提高并发性:即使在高并发情况下,也能保障数据库正常运行。

44.png

6. 总结

死锁检测机制就像“交警”,当它发现两辆车在十字路口互相堵住时,它会让其中一辆车退回去(回滚事务),从而让交通恢复畅通。这种机制帮助数据库在处理并发事务时,避免完全停滞的情况。