假设some_table
有两行,主键为1
和2
。以下语句序列可能会导致死锁:
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语句是否有可能以不同的顺序删除行?是否可以强制执行删除命令以避免死锁?
我在文档中找不到此信息,所以我说不能保证删除顺序(尽管它可能间接地作为实现细节)。我想在这里再次检查。
答案 0 :(得分:1)
是的,这可能导致死锁,因为表中的行顺序不是固定的。
任何UPDATE
可能会更改顺序表扫描返回的行的顺序,并且如果synchronize_seqscans
为其默认值on
,则即使表没有更改顺序也可能会更改。如果同时执行多个顺序扫描(如您的情况),则为t。
您应该首先运行带有SELECT ... FOR UPDATE
子句的ORDER BY
来减少出现死锁的风险,但是即使那样您也不能绝对确定,除非您对不会同时更新的列进行排序(如主键)。