在实现数据库查询时,我经常想知道当许多客户端并行执行时,我正在编写的查询是否会出现潜在的死锁。通常,我只能通过与大量客户机并行运行查询来发现,以查看是否在实践中得到了臭名昭著的“检测到死锁”。
我想知道是否有一种更正式的方法来确定查询是否有死锁的可能性?我所说的“更正式”的意思是:
发布于 2023-03-14 17:57:49
我不认为对此有一种有原则的正式办法。此外,尽管可能发生这种情况,但在第二个会话中运行同一个语句的单个语句死锁并不常见。通常,在同一事务中运行并同时接受锁的其他语句也同样重要。
减少死锁的可能性的简单技巧是:
这样做后,您可以通过确保资源总是按照一定的顺序锁定,从而争取更多的资源。这个顺序通常很难确定,并且将取决于语句所选择的执行计划(您可以在EXPLAIN中找到)。举个例子:
UPDATE tab
SET col = 42
WHERE val = 'changeme';不能保证按一定顺序锁定行。相反,您可以尝试以下一些比较昂贵的方法,但在这方面会做得更好:
WITH myrows AS (
SELECT id
FROM tab
WHERE val = 'changeme'
ORDER BY id
FOR NO KEY UPDATE
)
UPDATE tab
SET col = 42
FROM myrows
WHERE tab.id = myrows.id;我并不是说,后一种声明永远不会与任何东西陷入僵局,但与前一种声明相比,不与其自身陷入僵局的可能性更大。
https://dba.stackexchange.com/questions/324755
复制相似问题