Chapter 27 — Quiz

13 questions. Answers at the bottom.


Multiple choice

Q1. The lost-update problem occurs when: - A) Two transactions read the same value, each computes a new one, and one write overwrites the other - B) A transaction reads uncommitted data - C) A query is slow - D) An index is missing

Q2. SELECT ... FOR UPDATE: - A) Reads without locking - B) Reads and locks the row so others must wait to modify it - C) Deletes the row - D) Creates an index

Q3. Pessimistic concurrency control: - A) Assumes conflicts are rare and retries - B) Locks up front, assuming conflicts will happen - C) Never uses locks - D) Only works for reads

Q4. Optimistic concurrency control typically uses: - A) Table locks - B) A version column + compare-and-swap, retrying on conflict - C) Advisory locks - D) No transactions

Q5. A deadlock is: - A) A slow query - B) A cycle of transactions each waiting for a lock the other holds - C) A corrupted index - D) A crash

Q6. PostgreSQL handles a deadlock by: - A) Hanging forever - B) Detecting it and aborting one transaction (which should retry) - C) Ignoring it - D) Restarting the server

Q7. The main way to prevent deadlocks is: - A) More indexes - B) Acquiring locks in a consistent order across transactions - C) Bigger hardware - D) Read Uncommitted

Q8. Doing UPDATE x SET n = n - 1 WHERE ... in one statement: - A) Risks a lost update - B) Is atomic on the row, avoiding the read-modify-write race - C) Requires FOR UPDATE - D) Causes deadlocks

Q9. An advisory lock is for: - A) Locking a row - B) Application-defined coordination of non-row resources (a named mutex) - C) Indexing - D) Backups

Q10. Connection pooling solves: - A) Slow queries - B) Connection exhaustion from too many (often idle) connections at scale - C) Deadlocks - D) Missing indexes


True/False

Q11. Optimistic concurrency is best when contention on the same row is low. (True / False)

Q12. Deadlocks are catastrophic and should crash the application. (True / False)


Short answer

Q13. Two concurrent "buy the last item" requests both read stock = 1 and both succeed, overselling. Explain the bug and two ways to fix it.

---

Answer key

Q1 — A. Read-modify-write race; one increment/decrement is lost.

Q2 — B. Locks the row; others wait to modify it (pessimistic).

Q3 — B. Lock up front, assume conflict.

Q4 — B. Version column + compare-and-swap + retry.

Q5 — B. Cyclic lock wait.

Q6 — B. Detected; one transaction aborted; retry.

Q7 — B. Consistent lock ordering breaks the cycle.

Q8 — B. Single-statement arithmetic is atomic on the row.

Q9 — B. App-defined named lock for non-row coordination.

Q10 — B. Caps/reuses connections so the server isn't overwhelmed.

Q11 — True. Low contention → conflicts (and retries) are rare → optimistic wins.

Q12 — False. Deadlocks are recoverable; catch the error and retry the transaction.

Q13. It's a lost-update / read-modify-write race: both requests read stock = 1 before either decrements, so both pass the check and both sell. Fix 1 (pessimistic): SELECT quantity ... FOR UPDATE to lock the row, so the second request waits and sees stock = 0. Fix 2 (atomic SQL): UPDATE inventory SET quantity = quantity - 1 WHERE product_id = ... AND quantity > 0 in one statement and check that 1 row was affected — only one decrement can succeed when stock is 1. (Optimistic with a version column also works.)

Scoring: 11–13 you can build correct concurrent systems; 8–10 review lost updates and deadlocks; below 8, do the two-session exercises.