What does SELECT FOR UPDATE do and when would you use it?
`SELECT FOR UPDATE` is a SQL statement that reads rows and immediately acquires an exclusive row-level lock on them within the current transaction. Other transactions attempting to modify those rows — or acquire their own `SELECT FOR UPDATE` locks — will block until your transaction completes. Regular reads (without `FOR UPDATE` or `FOR SHARE`) are typically not blocked, depending on the isolation level and database engine.
The primary use case is pessimistic concurrency control: you want to read a value, make a decision based on it, and update it — guaranteeing that no other transaction can change those rows between your read and your write. A classic example is an inventory system: `SELECT quantity FROM inventory WHERE product_id = 42 FOR UPDATE`, followed by a check and `UPDATE inventory SET quantity = quantity - 1`. Without the lock, two concurrent transactions could both read quantity=1, both decide to decrement, and both commit — leaving quantity at -1.
Another common pattern is job queue processing: workers select a batch of pending jobs with `FOR UPDATE SKIP LOCKED` (supported in PostgreSQL, MySQL 8+, Oracle). `SKIP LOCKED` causes the query to skip rows already locked by other workers, enabling efficient parallel queue draining without contention or blocking.
Key operational considerations: `SELECT FOR UPDATE` escalates lock scope to all rows returned, so a poorly written predicate can lock large swaths of the table and cause cascading blocking. Lock duration is tied to transaction duration — long-running transactions holding these locks are a common source of production latency spikes. Deadlocks are also possible when two transactions lock rows in opposite orders; applications must handle deadlock errors with retry logic.
In PostgreSQL, `FOR UPDATE` can be qualified with `OF table_name` in joins to specify which table's rows to lock, avoiding unintended wide locks in complex queries.
Correctly describes exclusive row locking, explains the read-check-write pattern it protects, and gives a concrete use case like inventory decrement.
Covers SKIP LOCKED for queue processing, explains lock duration = transaction duration and its performance implications, mentions deadlock risk with retry requirements, and distinguishes from optimistic locking.
Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.
Get Graded — Free Assessment