Skip to content

Optimistic vs Pessimistic Locking ​

Two strategies to handle concurrent access to the same data.

  • Pessimistic → "Someone WILL conflict with me, let me lock first"
  • Optimistic → "Conflicts are RARE, let me just check at the end"

Pessimistic Locking ​

Acquire a lock before reading/writing. Other transactions must wait until lock is released. Lock is held for the entire duration of transaction.

sql
BEGIN;
SELECT * FROM accounts WHERE id = 1 FOR UPDATE; -- locks row immediately
UPDATE accounts SET balance = balance - 500 WHERE id = 1;
COMMIT; -- lock released

Types of Pessimistic Locks ​

  • Shared Lock (Read Lock): Multiple transactions can READ simultaneously. No one can WRITE while shared lock exists.
  • Exclusive Lock (Write Lock): Only ONE transaction can hold it. No one can READ or WRITE.

Optimistic Locking ​

No locks acquired upfront. Each row has a version number. At commit time → check if version has changed.

sql
-- Step 1: Read with version
SELECT balance, version FROM accounts WHERE id = 1;
-- returns balance=500, version=5

-- Step 2: Update only if version unchanged
UPDATE accounts SET balance = 400, version = version + 1
WHERE id = 1 AND version = 5;
-- if 0 rows updated → conflict detected! retry

Comparison ​

PessimisticOptimistic
Lock acquiredUpfrontNever (just version check)
Conflict handlingPrevent upfrontDetect at commit
WaitingYes, transactions waitNo waiting
Retry neededNoYes, on conflict
ThroughputLowerHigher
Best forHigh conflict scenariosLow conflict scenarios

When to Use Which ​

  • Pessimistic: High contention, can't afford retries, long transactions. Example: Bank transfer, seat booking.
  • Optimistic: Low contention, short transactions, high read/low write. Example: Social media likes, profile updates.
SystemApproachWhy
BankingPessimisticCan't lose updates
Airline bookingPessimisticLast seat conflicts
GitHub (git)OptimisticMerge conflicts rare
E-commerce cartOptimisticLow contention
Hibernate ORMOptimistic (default)General purpose