Skip to content
All writing ‹ Part 01 of 04 · Thread-Safe Login, the Hard Way
Engineering · 1 min read

A Mutex Gives You ACID's 'I', and Nothing Else

A mutex only guarantees ACID's Isolation property, not Atomicity, Consistency, or Durability. Here's why that gap causes half-finished state in concurrent code.

mutex Only Provides ACID’s “I”, Not A, C, or D

Wrapping login() in a lock looks as safe as wrapping it in a database transaction. But a lock only provides one of ACID’s four letters: I (Isolation).

Both a lock and a DB transaction serialize concurrent work, but the guarantees they provide differ a lot:

ACIDDB Transactionmutex
Atomicity (rollback)YesNo. A critical section that throws mid-way leaves a half-finished result
Consistency (invariants)Enforced by the engineMaintained by the code itself
IsolationYes (tunable)Yes. Similar to Serializable
DurabilityPersisted to diskNo (in-memory only)

Beyond this table, two structural differences are worth remembering:

  • A transaction protects data (enforced by the engine for all accessors). A mutex protects a code path (only threads that voluntarily acquire the same lock are protected).
  • It is “must end before the next one runs,” not “must succeed.” A failed transaction rolls back. A failed critical section can leave a mess for the next lock holder.

This is exactly why login() needs manual handling to avoid the rollback problem (finish first, then publish). A lock will not automatically undo a half-finished write.

A lock serializes “execution,” not “success.” Achieving atomicity takes manual work.


References:

Related: see the finish-first, then-publish safe publication pattern, or go back to the four-lesson overview on making login thread-safe.

↑↓ navigate ↵ open esc close