了解 Postgres 死锁

Understanding Postres Deadlock

我有一个带有 Flask 和 SQLAlchemy 的 Python Webapp,并且有一个在多线程中发生的系统更新过程。当我 运行 它时,我从 Postgres 得到一个死锁。

日志中出现的查询如下。

ERROR: deadlock detected
DETAIL:  Process 2269053 waits for ShareLock on transaction 42979254; blocked by process 2269014.
Process 2269014 waits for ShareLock on transaction 42979253; blocked by process 2269053.
Process 2269053: UPDATE sequence SET item_list='{"item_list": [162, 164]}' WHERE sequence.id = 1978

Process 2269014: UPDATE sequence SET item_list='{"item_list": [162, 165]}' WHERE sequence.id = 1977
HINT: See server log for query details.
while updating tuple (102,44) in relation "sequence"
STATEMENT:  UPDATE sequence SET item_list='{"item_list": [162, 164]}' WHERE sequence.id = 1978

我看到它们是 2 个不同的 PK,根据我的理解,当执行更新时只有行被锁定并且语句来自 2 个不同的行。显然我误会了什么,所以我想问问是否有人可以帮助我澄清为什么会发生这种死锁,我该如何解决?

谢谢

缺少的信息是一个事务可以跨越多个语句,并且每个语句都可以获取锁。因此,每个引用的 UPDATE 语句都被另一个事务中的 某些语句 获取的锁所阻塞。

例如,进程 2269053 的先前语句可能已将行更新为 id 1977,而进程 2269014 的先前语句可能已将行更新为 id 1978。有当然还有许多其他可能性。

您应该找出您的应用程序的哪一部分发出了这些语句(应用程序日志文件?)并查看这些事务之前做了什么。如果您无法通过查看代码重建它,您可能必须启动应用程序或数据库日志记录才能获取该信息。