Skip to content
Databases for Developers

Lesson 5 of 10 · 20 min

x
5/10

Lesson position in the course — not completion. Use Mark Complete to track finished lessons (saved in this browser).

Transactions & ACID

A transaction is a group of operations that either all succeed or all fail together. ACID is the set of guarantees that make this work: Atomicity (all-or-nothing), Consistency (data stays valid), Isolation (concurrent transactions don't interfere), and Durability (committed data survives crashes).

Isolation levels control how visible uncommitted changes are to other transactions. Read Committed (the Postgres default) prevents dirty reads but allows non-repeatable reads. Serializable provides the strongest guarantee but reduces concurrency. Most applications work well at Read Committed — only use Serializable for financial operations where phantom reads would cause real money problems.

Before
Unsafe — partial failure leaves dirty state
1// If second update fails, money disappears2await db.query(3  'UPDATE accounts SET balance = balance - 100 WHERE id = 1'4);5await db.query(6  'UPDATE accounts SET balance = balance + 100 WHERE id = 2'7);
After
Safe — both updates succeed or both roll back
1await db.query('BEGIN');2try {3  await db.query(4    'UPDATE accounts SET balance = balance - 100 WHERE id = 1'5  );6  await db.query(7    'UPDATE accounts SET balance = balance + 100 WHERE id = 2'8  );9  await db.query('COMMIT');10} catch (err) {11  await db.query('ROLLBACK');12  throw err;13}

Exercise

Wrap a two-step balance transfer (debit + credit) in BEGIN/COMMIT with ROLLBACK on error. Force a failure after the debit and confirm the debit did not stick. Note which isolation level your engine defaults to.

Previous

Progress is saved in this browser.

Next Lesson