ACID Properties

There is a standard list of four properties a transaction has. It goes by the acronym ACID: atomicity, consistency, isolation, durability. The name comes from a 1983 paper by Theo Härder and Andreas Reuter, and it has been the way people describe transactions since. We have now seen all four.

  • Atomicity is the promise that a transaction either applies all its writes or none of them. If anything goes wrong before COMMIT, the database undoes the writes it has already applied. We saw it in the purchase: the balance update and the ledger row take effect together or not at all.
  • Consistency is the promise that a transaction takes the database from a state where every constraint holds to another state where every constraint holds. A statement that would break a constraint is refused. We saw it in the refused purchase: the balance cannot go negative, whatever the application does.
  • Isolation is the promise that a transaction behaves as if it were the only one running, even when others run at the same time on the same rows. We saw it in the purchase and the reload: the reload waited for the purchase to finish and then read the balance the purchase left behind.
  • Durability is the promise that once the database says a transaction is committed, its changes are permanent. Even if the system crashes or loses power right after, the changes survive. We saw what the database does to keep it: the log record written to disk before it says “committed.”

Consistency is not quite like the other three. Atomicity, isolation, and durability are guarantees the database gives on its own. Consistency is only partly the database’s job. The database enforces the rules it was given as constraints, such as the balance never going negative. It knows no other rules. The rule that matters most for Dining Dollars, that the balance equals the sum of the ledger, spans two tables. The simple constraints in this schema do not enforce it. In this design, keeping that rule is the application’s job, and the database’s part is to make it possible by running the two writes in one transaction. Because so much of consistency rests on the application, some people say it does not belong on the list. Martin Kleppmann, in Designing Data-Intensive Applications, quotes Joe Hellerstein’s remark that the C was put in to make the acronym work.

The word consistency has another problem. It also names a property of distributed systems, and there it means keeping data consistent across the system, which may hold several copies of the same value. We will explore that in a future chapter. Here, consistency means the constraints on the data hold.

Why does this matter to you as a software designer? Each of these promises is something the application does not have to build. Without atomicity, the purchase code would have to detect a crash between its two writes and repair the balance. Without durability, it would have to confirm a purchase only after checking the disk itself. Without isolation, it would have to keep every transaction from touching the same rows at once. So if you are designing a system that needs these promises, you could benefit from using a database that gives them.

Relational databases give all four (especially when running on a single machine). That is a large part of why a relational database is the default choice for an application like Dining Dollars that needs ACID transactions.

Other kinds of databases may offer some of these promises. We will see them in a future chapter.