两个并发但相同的 DELETE 语句会导致死锁吗?

Can two concurrent but identical DELETE statements cause a deadlock?

假设 some_table 有两行,主键为 12。以下语句序列可能会导致死锁:

session 1: begin;
session 2: begin;
session 1: DELETE FROM my_table WHERE my_key = 1;
session 2: DELETE FROM my_table WHERE my_key = 2;
session 1: DELETE FROM my_table WHERE my_key = 2;
session 2: DELETE FROM my_table WHERE my_key = 1;

如果两个会话按相同的顺序删除,就不会发生死锁。

现在,回到我的问题,如果 DELETE 语句涉及多行会怎样?例如:

session 1: begin;
session 2: begin;
session 1: DELETE FROM my_table;
session 2: DELETE FROM my_table;

是否有可能两个并发但相同的 DELETE 语句会以不同的顺序删除行?是否可以强制执行删除顺序以避免死锁?

我在文档中找不到此信息,所以我想说不能保证删除顺序(尽管它可能是间接的实现细节)。我想在这里仔细检查一下。

是的,这可能会导致死锁,因为 table 中行的顺序不固定。

任何 UPDATE 可能会更改顺序 table 扫描返回的行的顺序,如果 synchronize_seqscans 处于其默认值 on,则顺序可能会更改即使 table 没有同时执行多个顺序扫描(如您的情况)。

您应该首先 运行 带有 ORDER BY 子句的 SELECT ... FOR UPDATE 以减少死锁的风险,但即便如此您也不能绝对确定,除非您按列排序不会同时更新(如主键)。