2/16/2026 at 10:06:48 PM
One pattern I've found useful alongside this: Postgres advisory locks (pg_advisory_xact_lock) for cases where the contention isn't row-level but logic-level. For example, if two requests try to create the "first" resource of a type - there's no existing row to SELECT FOR UPDATE against.Advisory locks let you serialize on an arbitrary key (like a hash of the entity type + parent ID) without needing a dummy row or separate lock table. They auto-release on transaction end, so no cleanup.
The barrier testing approach from the article would work nicely here too - inject the barrier between acquiring the advisory lock and the subsequent insert, then verify the second transaction blocks until the first commits.
by anvevoice
2/16/2026 at 10:12:39 PM
Nice - that's a good case for barriers too. When there's no row to SELECT FOR UPDATE against, you'd inject the barrier after acquiring the advisory lock and verify the second transaction blocks until the first commits.by lirbank
2/16/2026 at 11:21:03 PM
Seems like a good way to materialize the conflict.by klysm
2/17/2026 at 12:01:59 AM
I always did "INSERT ... ON CONFLICT DO NOTHING".by deepsun