两个并发但相同的 DELETE 语句会导致死锁吗?
Can two concurrent but identical DELETE statements cause a deadlock?
假设 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 语句会以不同的顺序删除行?是否可以强制执行删除顺序以避免死锁?
我在文档中找不到此信息,所以我想说不能保证删除顺序(尽管它可能是间接的实现细节)。我想在这里仔细检查一下。
是的,这可能会导致死锁,因为 table 中行的顺序不固定。
任何 UPDATE
可能会更改顺序 table 扫描返回的行的顺序,如果 synchronize_seqscans
处于其默认值 on
,则顺序可能会更改即使 table 没有同时执行多个顺序扫描(如您的情况)。
您应该首先 运行 带有 ORDER BY
子句的 SELECT ... FOR UPDATE
以减少死锁的风险,但即便如此您也不能绝对确定,除非您按列排序不会同时更新(如主键)。
假设 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 语句会以不同的顺序删除行?是否可以强制执行删除顺序以避免死锁?
我在文档中找不到此信息,所以我想说不能保证删除顺序(尽管它可能是间接的实现细节)。我想在这里仔细检查一下。
是的,这可能会导致死锁,因为 table 中行的顺序不固定。
任何 UPDATE
可能会更改顺序 table 扫描返回的行的顺序,如果 synchronize_seqscans
处于其默认值 on
,则顺序可能会更改即使 table 没有同时执行多个顺序扫描(如您的情况)。
您应该首先 运行 带有 ORDER BY
子句的 SELECT ... FOR UPDATE
以减少死锁的风险,但即便如此您也不能绝对确定,除非您按列排序不会同时更新(如主键)。