beginner~2h

Atomicity

The "A" in ACID, and the property Chapter 01's entire bank story was really about. This chapter goes from the plain-English idea to exactly how a database engine pulls it off.

LevelDefinition
BeginnerAll the steps in a transaction happen together, like a single action — or none of them happen at all.
TechnicalAtomicity guarantees that a transaction's set of operations is applied as an indivisible unit — a partial application is never observable, whether the transaction succeeds, fails midway, or the system crashes.
Interview-gradeAtomicity is implemented via undo logging (or an MVCC equivalent): every change a transaction makes is recorded such that it can be fully reversed, and the database guarantees that either every recorded change is made permanent at commit, or every one is reversed at rollback or crash recovery.

◆ Story

An ATM withdrawal is really two separate database-level (or system-level) effects: debit the account, and signal the cash dispenser. Picture the exact moment the machine's power fails between those two effects. Without atomicity, you either lose money (debited, no cash) or the bank loses money (cash dispensed, never debited) — and crucially, nobody chose either outcome; it's purely an accident of timing. Atomicity's entire job is to make that accident of timing impossible to observe: the debit is either fully applied or fully un-applied, deterministically, regardless of exactly when the crash happened.

◆ Under the hood

Most relational databases (PostgreSQL, MySQL/InnoDB) implement atomicity using an undo log: before a transaction modifies a row, the database first records the row's previous value in the undo log. If the transaction commits, the undo log entries for it are simply discarded — they're no longer needed. If the transaction rolls back (explicitly, or because the connection dies, or because the whole server crashes and restarts), the database walks the undo log backward and restores every changed row to its recorded previous value. This is exactly how a crash mid-transaction is recoverable: on restart, the database finds any transaction that has an undo log but no commit record, and rolls it back automatically as part of crash recovery — you never have to detect or handle this yourself.

The undo log is written before the actual row is modified — this ordering is what makes rollback and crash recovery possible even if the crash happens mid-write.

BEGIN; UPDATE accounts SET balance = balance - 10000 WHERE id = 'A'; UPDATE accounts SET balance = balance + 10000 WHERE id = 'B'; -- if BOTH updates succeeded: COMMIT; -- if EITHER failed (e.g. account B doesn't exist, constraint violation): ROLLBACK;
@Transactional public void transfer(String fromId, String toId, BigDecimal amount) { Account from = accountRepository.findById(fromId).orElseThrow(); Account to = accountRepository.findById(toId).orElseThrow(); if (from.getBalance().compareTo(amount) < 0) { throw new InsufficientFundsException(fromId); // triggers rollback of BOTH updates below — see Chapter 08 } from.setBalance(from.getBalance().subtract(amount)); to.setBalance(to.getBalance().add(amount)); // no explicit commit call — Spring commits automatically if the method returns normally }

💻 Code example

BEGIN; UPDATE accounts SET balance = balance - 10000 WHERE id = 'A'; UPDATE accounts SET balance = balance + 10000 WHERE id = 'B'; -- if BOTH updates succeeded: COMMIT; -- if EITHER failed (e.g. account B doesn't exist, constraint violation): ROLLBACK;
FailureGuaranteed outcome
Application throws an exception mid-transferROLLBACK — neither account is changed
Database server crashes after the first UPDATE, before COMMITROLLBACK — undo log replayed on restart
Network connection drops after both UPDATEs but before COMMIT is acknowledgedROLLBACK — an uncommitted transaction is never made durable
Both UPDATEs succeed and COMMIT is acknowledgedCOMMIT — both changes are permanent (Durability, Chapter 05)

▲ Common mistake

Atomicity guarantees "all statements in the transaction," not "all side effects of my business logic." Sending a confirmation email or calling a third-party payment API inside a database transaction is not rolled back by a database ROLLBACK — the email still sends, the API call still fired. This is precisely the seed of the distributed transaction problem covered starting in Chapter 15: atomicity is a database-transaction concept, not a "my whole method" concept.

Want a visual for this concept?

Generate a diagram tailored to “Atomicity” — the AI picks whichever visual (flowchart, comparison, sequence, etc.) best fits.

Sign in to generate a visual →

Practice quiz

Next Step

Continue to Consistency← Back to all Transaction Mastery chapters