Question presented to candidate:
"You need to lock a row before you change it. PostgreSQL gives you FOR UPDATE, FOR UPDATE NOWAIT and FOR UPDATE SKIP LOCKED. What does each one do when the row is already locked, and which would you pick for a seat-booking page, a background job queue and a money transfer?"
What a strong answer should cover:
FOR UPDATElocks the selected rows until the transaction ends; a second locker waits for the first to commit or roll backNOWAITturns that wait into an immediate error, SQLSTATE55P03;SKIP LOCKEDsilently leaves locked rows out of the result- Plain SELECTs are never blocked by any of them (MVCC); only other locking reads and writes are
- Use cases: plain
FOR UPDATEwhen every caller must see and process this exact row (transfers, with a consistent lock order);NOWAITfor "someone else is editing, try later" in interactive flows;SKIP LOCKEDfor queues and pools where any free row will do - Details:
lock_timeoutas the middle ground between waiting forever and failing at once; after waiting, READ COMMITTED re-checks the WHERE clause on the new row version;FOR NO KEY UPDATEis weaker and does not block foreign-key inserts - Engines: PostgreSQL has had SKIP LOCKED since 9.5, MySQL 8.0 has NOWAIT and SKIP LOCKED, SQL Server uses
UPDLOCK, READPASThints, SQLite has no row locks at all
Code / implementation expected: Yes — the three clauses on the same locked row, with what each one returns.
Schema used by the examples: