这是表格(简化):
Table "public.link" Column | Type | Modifiers ---------------+-----------------------------+--------------------------------------------------- id | integer | not null default nextval('link_id_seq'::regclass) page_id | integer | placed_at | timestamp without time zone | default now() Indexes: "link_pkey" PRIMARY KEY, btree (id) "link_page_id_index" btree (page_id) Foreign-key constraints: "link_page_id_foreign_key" FOREIGN KEY (page_id) REFERENCES page(id) ON UPDATE RESTRICT ON DELETE RESTRICT
这里是查询(简化):
UPDATE link SET page_id = ?, placed_at = now()
WHERE id IN ( SELECT id FROM link ... ) AND page_id IS NOT NULL
死锁消息:
ERROR: deadlock detected Detail: Process 5822 waits for ShareLock on transaction 19705; blocked by process 5821. Process 5821 waits for ShareLock on transaction 19706; blocked by process 5822. Hint: See server log for query details.
由多个进程并行执行的查询如何导致死锁?
谢谢!
最佳答案
session A 尝试更新 ID 10、2、30、4, session B 尝试更新 ID 40、30、20、10
他们都尝试锁定各自的行以准备更新,A 获得 10 并等待 30,而 B 获得 30 并等待 10。死锁。
您的根本问题是您正在尝试更新并发事务中的(部分)相同 ID。
如果不了解您的数据库结构以及您正在尝试做什么,就很难提出最佳解决方案。通常,您要么确保不同的后端不会更新相同的行,要么减少超时并在随机暂停后重试。
关于Postgresql -> 来自简单更新的死锁。我找不到原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12856192/