Skip to main content

ACID Properties: What Each Actually Guarantees

What This Concept Is

ACID is four independent guarantees that a transaction-capable database can offer. People quote the acronym but usually blur the four together. Pulling them apart is the first step of this module.

  • Atomicity: a transaction runs entirely or not at all. A crash or error mid-transaction rolls back every effect. Atomicity does not imply concurrency safety; it is purely about all-or-nothing effect in the face of failure.
  • Consistency: the transaction takes the database from one valid state to another, where "valid" means application-level invariants and declared constraints (uniqueness, foreign keys, check constraints) hold. The letter C is the odd one out: the database only enforces the constraints the application declares. The rest is the application's responsibility.
  • Isolation: concurrent transactions do not see each other's in-progress effects. The strongest form is serializability: the result is as if transactions ran one after another in some order.
  • Durability: once a transaction has committed, its effects survive crashes, power loss, and most disk faults.

The confusion starts because the machinery that implements each letter is different: write-ahead logging and recovery for A and D, constraint checking and application logic for C, concurrency control for I.

Why It Matters Here

Every later concept in the module maps to one of these letters. When you later ask "why does snapshot isolation prevent phantoms but still allow write skew," you are asking an I question, not an A or D question. When you ask "why does my transaction succeed but leave an inconsistent balance," the answer is almost always that you wrote a C bug in application logic rather than that the database failed you. When a vendor says "ACID-compliant," the honest version of that claim is "we honor A and D without qualification, we implement I at some level you can configure, and we enforce only the C constraints you declared."

Concrete Example

Transfer $100 from account A to B. Initial balances: A = 500, B = 200. The transaction is:

BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 'A';
UPDATE accounts SET balance = balance + 100 WHERE id = 'B';
COMMIT;

Which letter catches which failure:

  • Crash between the two UPDATEs: Atomicity rolls back the first UPDATE so A is not charged.
  • Someone issues a concurrent DELETE FROM accounts WHERE id='A': Isolation either blocks that delete, serializes around the transfer, or aborts one of the two.
  • A CHECK constraint says balance >= 0 and A only had $50: Consistency (constraint enforcement) rejects the transaction.
  • The system crashes at fsync time after COMMIT returns: Durability replays the WAL and reapplies the commit.

Application-level invariants like "total money in the system is conserved" are your responsibility: the DB does not know that. It enforces the constraints you declared.

Common Confusion / Misconception

"ACID means serializable." No. Most real databases default to weaker isolation (Read Committed or Snapshot Isolation) and still honestly call themselves ACID. I is configurable.

"Consistency is a database guarantee." Only the part that corresponds to declared constraints. The rest is application logic. Kleppmann explicitly calls C "an ill-fitting property that was shoehorned into the acronym."

"Durability means the disk cannot lose my data." Durability means the database has done everything required to survive a crash at the layer it controls. If fsync lied to it (flash caches) or the disk physically burns, durability is beyond scope. Durability is an assumption-relative guarantee.

How To Use It

Whenever you are debugging or designing a transaction, label the property you are reasoning about:

  1. "Can a crash at this point leave the database in a bad state?" - A and D question.
  2. "Can a constraint I care about be violated?" - C question; check that the constraint is actually declared.
  3. "Can two concurrent transactions interleave to produce a state that is not reachable by any serial order?" - I question, and the answer depends on the isolation level.

Never answer one with the machinery of another.

Check Yourself

  1. Which of A, C, I, D does a uniqueness constraint on email address enforce?
  2. A transaction that reads a value, performs a computation, and writes a new value can still produce wrong results even under serializable isolation. What property does that violate, and who is responsible for preventing it?
  3. If your database's fsync is disabled for speed, which letter is no longer guaranteed?
  4. Why is it correct to say "ACID is four independent guarantees" rather than "ACID is one guarantee"?

Mini Drill or Application

Classify each scenario as primarily an A, C, I, or D failure:

  1. A credit card is charged but the order record never appears because the database crashed between the two INSERTs.
  2. Two concurrent UPDATE counter SET n = n + 1 calls leave n incremented by 1 instead of 2.
  3. A foreign key references a now-deleted row.
  4. After a power loss, the last 100 committed writes are missing.
  5. A read sees half of a logical update: one row updated, another not yet.

Read This Only If Stuck