我正在读一遍又一遍的迈克尔·尼加德(Michael Nygard)的书“发布它!”。而且我仍然不明白为什么会发生确切的死锁:
想象一下,有100,000个事务都试图更新交易记录的同一行 同一数据库中的同一表。有人注定会陷入僵局。 锁定用户资料的单笔交易一旦挂起 (因为需要来自其他资源池的连接), 该行上的所有其他数据库事务均被阻止。漂亮 很快,每个请求处理线程都用光了 假登录。一旦发生这种情况,该站点就会关闭。
当他说“由于需要来自不同资源池的连接”时,这是数据库引擎内部吗?这个其他资源池是什么?为什么需要来自另一个资源池的连接?
然后,“每个请求处理线程”已经不是指数据库线程,而是指应用程序线程,对吗?他们之所以挂起,是因为他们正在等待已挂起的数据库事务完成?
答案 0 :(得分:1)
问题在于应用程序与很多不同的系统接口,其中任何一个系统都可以并行运行,具有内部或外部锁,并且依赖于更多系统。
一个简单的死锁示例基本上是当两个进程需要同时获取完全相同的两个锁才能继续进行时,但是不同意谁先执行和以哪个顺序执行(通常是什么锁)首先是要解决的,所以这是个鸡到蛋的问题,并不完全是琐碎的)。因此,进程A和B需要获取两个锁#1和#2,以执行其操作并继续。但是当A锁定#1时,B锁定#2,然后A尝试锁定#2,B尝试锁定#1-那是死锁。要做任何工作都必须让步。
在现实生活中,假设您正在运行Web应用程序的多个实例,以便能够同时满足多个传入的客户端请求(例如Web浏览器)。这些是线程,进程还是协程都没关系。如果您的应用程序实例需要锁定两个数据库行,则它们可能会挂起。或者它们可以挂起,因为除了数据库锁定之外,它们还需要在文件系统中的文件上锁定。或者它们可能会挂起,因为它们需要在文件系统中锁定文件,并且正在使用第三方远程REST API,该API也具有自己的锁。或由于无限的其他原因(包括上述所有原因)。