Menu

Earn Premium with Referrals

Invite your friends and earn Premium rewards through our referral program.

See how it works and start inviting friends.

Locks & Deadlocks
SQL

Locks & Deadlocks

Learn how databases manage resource contention and how to resolve the dreaded deadlock.

Locks are the mechanism used by databases to manage simultaneous access to data. They prevent multiple transactions from changing the same piece of data at the same time.

Types of Locks

  1. Shared (S) Lock: Allows multiple transactions to read a resource but prevents any from writing (common during SELECT).
  2. Exclusive (X) Lock: Prevents all other transactions from accessing the resource (common during UPDATE, DELETE).
  3. Intent Locks: Used to indicate that a transaction plans to acquire a lock at a lower level (e.g., row-level) to prevent table-level changes.

Lock Granularity

LevelScopeOverhead
RowSingle rowLow (most concurrency)
PageDisk page (multiple rows)Medium
TableEntire tableHigh (least concurrency)
DatabaseEntire databaseVery high

Databases start at row-level and may escalate to page or table locks when too many row locks are held.

MVCC — Multi-Version Concurrency Control

MVCC is NOT a locking mechanism — it is an alternative to locking for reads. Instead of acquiring a shared lock, readers see a “snapshot” of the data as of a point in time.

How it works:

  • When a row is updated, the old version is preserved.
  • Each transaction sees the version that was current when it started (or when the statement started, depending on isolation level).
  • Writers still need exclusive locks to prevent conflicting writes.

Deadlocks

A deadlock occurs when two transactions are each waiting for the other to release a lock.

Transaction A: UPDATE accounts SET bal = 100 WHERE id = 1;
               -- now needs id = 2
Transaction B: UPDATE accounts SET bal = 200 WHERE id = 2;
               -- now needs id = 1

Result: A waits for B, B waits for A. Stalemate.

Deadlock Detection

Most databases have a deadlock detector that runs periodically (e.g., every second). When a deadlock is found:

  1. The engine chooses a “victim” (usually the transaction with the least work done).
  2. The victim’s transaction is terminated and rolled back.
  3. The other transaction proceeds normally.
  4. The application receives a deadlock error and must retry.

How to Avoid Deadlocks

  1. Access tables in the same order in all transactions. If all transactions update A before B, cycles cannot form.
  2. Keep transactions short. The shorter the transaction, the fewer locks held simultaneously.
  3. Avoid user interaction inside a transaction. Don’t wait for user input while holding locks.
  4. Use lower isolation levels. Serializable increases lock contention significantly.
  5. Use index-based lookups. Without an index, a row-level UPDATE might lock the entire table.

Optimistic vs Pessimistic Locking

ApproachHow It WorksBest For
Pessimistic (SELECT FOR UPDATE)Locks rows immediatelyHigh contention, short transactions
Optimistic (version column)Checks for conflicts at commit timeLow contention, long transactions

Explicit Locking

-- Lock a specific row for update (pessimistic)
SELECT * FROM accounts WHERE id = 1 FOR UPDATE;

-- Lock a table
LOCK TABLE accounts IN EXCLUSIVE MODE;

Q: What is MVCC (Multi-Version Concurrency Control)?

A: MVCC allows a database to provide “snapshots” of data to different transactions. Instead of locking a row for reading, the DB keeps multiple versions of the row. This allows users to read data without blocking writers, and vice versa. It is used by PostgreSQL and MySQL (InnoDB).

Q: What is WITH (NOLOCK) in SQL Server?

A: It is a hint that tells the database to read data without acquiring a shared lock. This is faster and avoids blocking but can result in “Dirty Reads” (reading uncommitted data).

Q: How do databases handle deadlocks?

A: Most modern databases have a deadlock detector. When a deadlock is found, the engine chooses one transaction as a “victim”, terminates it, and rolls it back, allowing the other transaction to proceed.

Q: What is Lock Escalation?

A: When a transaction acquires too many low-level locks (e.g., thousands of row locks), the database might “escalate” them into a single high-level lock (e.g., a table lock) to save memory, potentially blocking other users.

1. Demonstrate a Deadlock.

  1. TX A: UPDATE Accounts SET bal = 100 WHERE id = 1; (Holds lock on 1)
  2. TX B: UPDATE Accounts SET bal = 200 WHERE id = 2; (Holds lock on 2)
  3. TX A: UPDATE Accounts SET bal = 300 WHERE id = 2; (Waits for TX B)
  4. TX B: UPDATE Accounts SET bal = 400 WHERE id = 1; (DEADLOCK!)

2. How to avoid deadlocks?

Solution:

  • Always access tables in the same order in all transactions.
  • Keep transactions as short as possible.
  • Avoid user interaction inside a transaction.
  • Use lower isolation levels if the business logic allows.

3. What happens when a deadlock is detected?

A: The database picks a victim transaction (usually the one that has done the least work), rolls it back, and lets the other transaction proceed. The application receives an error like “ERROR: deadlock detected” and should retry.

4. Optimistic vs Pessimistic locking for an inventory system?

Explanation:

  • Pessimistic: SELECT quantity FROM products WHERE id = 1 FOR UPDATE; — locks the row immediately. Best for high-contention items (limited stock flash sales).
  • Optimistic: Uses a version column; checks at UPDATE time that the version hasn’t changed. Best for low-contention systems where conflicts are rare.

My Private Notes

Notes are auto-saved locally to this device.