What each ACID property actually guarantees — and what it doesn't
ACID is the contract a relational database makes with you. Without it, concurrent writes and crashes produce corrupted data — partial transfers, duplicate charges, lost updates. Every engineer who writes database-backed code is implicitly relying on ACID. Knowing what each letter actually guarantees — and doesn't — lets you write correct application code and spot designs that silently violate the contract.
Atomicity: a transaction is all or nothing — partial commits don't exist. Consistency: constraints (foreign keys, CHECK) hold before and after every transaction. Isolation: concurrent transactions behave as if they ran serially. Durability: once committed, data survives crashes.
Of the four, Isolation is the most nuanced — databases offer different isolation levels that trade correctness for performance. Full serializability is correct but slow; weaker levels allow anomalies in exchange for higher concurrency.
Postgres's default Read Committed prevents dirty reads but allows non-repeatable reads — a transaction may see different values for the same row if another transaction commits between its reads. Use Repeatable Read or Serializable when your logic depends on stable reads within a transaction.