To wait for a not-yet-committed INSERT
you'd need to take a predicate lock. There's limited predicate locking in PostgreSQL for the serializable support, but it's not exposed directly to the user.
Simple SERIALIZABLE
isolation won't help you here, because SERIALIZABLE
only requires that there be an order in which the transactions could've occurred to produce a consistent result. In your case this ordering is SELECT
followed by INSERT
.
The only option I can think of is to take an ACCESS EXCLUSIVE
lock on the table before INSERT
ing. This will only get released at COMMIT PREPARED
or ROLLBACK PREPARED
time, and in the mean time any other queries will wait for the lock. You can enforce this via a BEFORE
trigger to avoid the need to change the app. You'll probably get the odd deadlock and rollback if you do it that way, though, because INSERT
will take a lower lock then you'll attempt lock promotion in the trigger. If possible it's better to run the LOCK TABLE ... IN ACCESS EXCLUSIVE MODE
command before the INSERT
.
As you've alluded to, this is mostly an application mis-design problem. Expecting to see not-yet-committed rows doesn't really make any sense.