Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can two "SELECT FOR UPDATE" statements on the same table cause a deadlock?

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!

like image 261
Steve A Avatar asked Oct 10 '12 18:10

Steve A


People also ask

Can SELECT statements cause deadlocks?

It occurs due to a conflict between the select statement and the DML (insert, update and delete) statements. Usually, SQL Server chooses the select statement as a deadlock victim because it does not cause data changes and the rollback is quick.

Does SELECT for update lock table?

The SELECT FOR UPDATE statement is used to order transactions by controlling concurrent access to one or more rows of a table. It works by locking the rows returned by a selection query, such that other transactions trying to access those rows are forced to wait for the transaction that locked the rows to finish.

What is the most likely cause of a deadlock in SQL Server?

A deadlock happens when two (or more) transactions block each other by holding locks on resources that each of the transactions also need. For example: Transaction 1 holds a lock on Table A. Transaction 2 holds a lock on Table B.

How can we avoid deadlock while updating SQL Server?

Update lock (U) is used to avoid deadlocks. Unlike the Exclusive lock, the Update lock places a Shared lock on a resource that already has another shared lock on it.


1 Answers

Sorry, I had another answer but it was wrong.

The documentation states that an ORDER BY clause is applied before the FOR UPDATE clause. So the locks are acquired in whatever order the rows are selected (I have confirmed as such by testing). If you need to select them in a different order, you can use:

SELECT * FROM (SELECT * FROM table ORDER BY id FOR UPDATE) ORDER BY another_column;

You may want to try your question on the PostgreSQL mailing list.

like image 184
Dondi Michael Stroma Avatar answered Sep 23 '22 16:09

Dondi Michael Stroma