A Mutex Only Provides ACID's Isolation, Not the Rest
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:
| ACID | DB Transaction | mutex |
|---|---|---|
| Atomicity (rollback) | Yes | No — a critical section that throws mid-way leaves a half-finished result |
| Consistency (invariants) | Enforced by the engine | Maintained by the code itself |
| Isolation | Yes (tunable) | Yes — similar to Serializable |
| Durability | Persisted to disk | No (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’s “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 won’t automatically undo a half-finished write.
A lock serializes “execution,” not “success.” Achieving atomicity takes manual work.
References:
- http://ithare.com/databases-101-acid-mvcc-vs-locks-transaction-isolation-levels-and-concurrency/
- https://www.designgurus.io/blog/acid-database-transaction
Related: see the finish-first, then-publish safe publication pattern, or go back to the four-lesson overview on making login thread-safe.