Suppose that two simultaneous transactions execute the following queries on a Postgresql DB:
Transaction A:
SELECT * FROM mytable WHERE id IN (1, 2, 3, 4) FOR UPDATE
Transaction B:
SELECT * FROM mytable WHERE id IN (6, 3, 2, 1) FOR UPDATE
Is it possible for a deadlock to occur due to Postgresql acquiring row locks in an inconsistent order? E.g. if Postgresql were to acquire row locks in the order the ids are given in this example, then there is a potential for deadlock.
Or is Postgresql internally intelligent enough to always acquire row locks in a way that simultaneous, discrete SELECT FOR UPDATE
statements on the same table cannot deadlock each other (e.g. by always acquiring row locks in order of primary key)?
If Postgresql doesn't automatically prevent such deadlocks from occurring, is there a way to modify the queries to prevent such a situation (e.g. if in fact Postgresql acquires row locks in the order the ids are given, then consistently sorting the ids should prevent deadlock)?
Thanks for any help!
IN( .. , ..)
set does not imply an ordered set. It is just a set (collection of items), similar to the result ofselect ...
which is an (unordered) collection of tuples. In other words: the order of evaluation / execution is undefined – FirehouseSET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
That way, the second SELECT would be rejected. – Joaniejoann