Postgresql – Is it possible to make a SELECT wait until an ongoing UPDATE finishes

concurrencylockingpostgresqlselectupdate

Suppose that I am implementing a bank account logic using PostgreSQL. At some point, I will want to check if the user has sufficient balance to perform an operation. However, the user's balance might be in the middle of an UPDATE statement and, in my perception, any SELECT statements performed during this period will return the old balance. My questions are:

  1. Is my perception correct, i.e. is it possible for the SELECT statement to get old data in this trivial scenario?

  2. If yes, how do I implement locks to protect myself from this? I've read about FOR UPDATE in the docs, but I'm not sure it is meant for this specific situation.

Please assume that I cannot serialize the requests in the clients.

Best Answer

Yes, a SELECT...FOR UPDATE will block the select if the same row was already updated in another transaction which is still open.

A more general solution would be to run your transactions under the serializable isolation level, rather than using FOR UPDATE. This might not block the SELECT, but would instead deliver an ERROR to the transaction later when it detected that a non-serializable situation has developed.