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

时间:2018-08-22 15:03:53

标签: sql postgresql postgresql-9.5 database-deadlocks

假设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语句是否有可能以不同的顺序删除行?是否可以强制执行删除命令以避免死锁?

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

1 个答案:

答案 0 :(得分:1)

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

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

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