理解PostgreSQL死锁

4

我有一个基于Flask和SQLAlchemy的Python Web应用程序,并且有一个在多个线程中发生系统更新的过程。当我运行它时,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个不同的主键,据我了解,当进行更新时,只会锁定该行,并且语句来自2个不同的行。显然我有些误解,所以我想问一下是否有人可以帮助我澄清为什么会发生死锁,以及如何解决它?
谢谢
1个回答

2
缺失的信息是一个事务可以跨越多个语句,并且每个语句都可以获取锁。因此,引用的每个UPDATE语句都会被另一个事务中某个语句获取的锁所阻塞。
例如,进程2269053的上一个语句可能已更新了id为1977的行,而进程2269014的上一个语句可能已更新了id为1978的行。当然还有许多其他可能性。
您应该找出应用程序发出这些语句的部分(应用程序日志文件?)并查看这些事务之前所做的事情。如果不能通过查看代码重构它,则可能需要增加应用程序或数据库记录以获取该信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接