Assume some_table
has two rows, with primary key 1
and 2
. The following sequence of statements can cause a deadlock:
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;
The deadlock would not have occurred if both sessions deleted in the same order.
Now, coming to my question, what happens if the DELETE statement touches multiple rows? For example:
session 1: begin;
session 2: begin;
session 1: DELETE FROM my_table;
session 2: DELETE FROM my_table;
Is it possible that two concurrent but identical DELETE statements will delete rows in a different order? Is it possible to enforce the deletion order to avoid a deadlock?
I could not find this information in the documentation, so I would say that deletion order is not guaranteed (although it might be indirectly as an implementation detail). I wanted to double check here.
DELETE
statement (that is, as early as possible). It should not be delayed until theCOMMIT
statement, which is indeed absent here. My question is not about a trivial deadlock due to the absence of aCOMMIT
statement. – MccleanSELECT FOR UPDATE
prior to theDELETE
would be unnecessary if the rows are always deleted in the same order or there if there was a way to enforce deletion order. If not, aSELECT ... ORDER BY ... FOR UPDATE (SKIP LOCKED)
could be useful indeed. – MccleanFOR UPDATE
, I am not sure if that works as we would expect. See #51972702 – Mcclean