DATABASES / SYSTEM CONCEPT BRIEF

Database transactions

A transaction groups several operations into one unit that either fully succeeds or has no effect.

IntermediatePhase 04 / Topic 16 of 16RequirementsTrade-offsFailure modes
01

Overview

A transaction groups several operations into one unit that either fully succeeds or has no effect. ACID describes the guarantees: Atomicity (all or nothing), Consistency (constraints hold), Isolation (concurrent transactions do not see each other's partial work), and Durability (committed data survives crashes).

Isolation levels trade correctness for concurrency. Read Committed (the default in PostgreSQL) prevents dirty reads but allows lost updates and write skew unless you lock or check; Repeatable Read gives a consistent snapshot; Serializable makes concurrent transactions behave as if they ran one at a time, at the cost of retries. Knowing which anomalies each level allows is essential for correct money and inventory logic.

A bank teller's transfer slip

Moving money from savings to checking is one slip: the teller never debits one account without crediting the other. If the power fails halfway, the slip is voided and both balances are untouched.

02

When to use it

  • Money transfers, orders, bookings, inventory updates.
  • Any multi-row or multi-table change that must stay consistent.
  • Preventing race conditions between concurrent requests.
  • Implementing job queues and counters safely.
03

Where it shows up in interviews

Preventing double booking

Recognize it when: two users try to book the last seat.

  • Design a ticket booking system
  • Design a hotel reservation system
Money movement

Recognize it when: balances must never go negative or lose money.

  • Design a payment wallet
  • Design a ledger service
04

Where it is used in real software

Double-entry ledgers

Payment companies record every movement as balanced debit and credit entries inside one transaction.

SELECT FOR UPDATE

Booking systems lock the seat row during checkout so two transactions cannot both claim it.

Serializable in CockroachDB

CockroachDB defaults to serializable isolation and asks clients to retry on conflicts.

05

Key terms

Atomicity
All operations commit or none do (rollback).
Isolation level
How much concurrent transactions can see of each other.
Dirty read / non-repeatable read / phantom
Reading uncommitted data / a row changing between reads / new rows appearing.
Lost update
Two transactions read, modify, and write the same row; one overwrites the other.
Optimistic vs pessimistic locking
Check a version at write time vs lock rows up front.
06

How it works, step by step

  1. 1
    BEGIN

    Start the transaction.

  2. 2
    Read what you need, locking if necessary

    SELECT ... FOR UPDATE for rows you will change based on their value.

  3. 3
    Validate business rules

    Balance sufficient, seat still available.

  4. 4
    Write changes

    Updates and inserts across tables.

  5. 5
    COMMIT or ROLLBACK

    On serialization failures, retry the whole transaction.

07

The lost update anomaly

Balance = 100; two withdrawals of 30 at the same time, read-modify-write without locking

Step 1 / 4
StepTransaction ATransaction BBalance in DB
1read balance: 100-100
2-read balance: 100100
3write 100 - 30 = 70-70
4-write 100 - 30 = 7070 (should be 40)

NOWStep: 1 | Transaction A: read balance: 100 | Transaction B: - | Balance in DB: 100

Fixes: atomic update (SET balance = balance - 30 WHERE balance >= 30), SELECT FOR UPDATE, optimistic locking with a version column, or Serializable isolation with retries.

08

Implementation

-- Book the last seat safely (pessimistic lock)BEGIN;SELECT id FROM seats WHERE event_id = 7 AND seat_no = 'A12' AND status = 'available'FOR UPDATE;                                  -- second transaction waits hereUPDATE seats SET status = 'held', held_by = 42, held_until = now() + interval '10 minutes'WHERE event_id = 7 AND seat_no = 'A12';COMMIT; -- Atomic conditional update: no read-then-write raceUPDATE accounts SET balance = balance - 30 WHERE id = 1 AND balance >= 30;-- 0 rows updated means insufficient funds -- Optimistic locking with a version columnUPDATE documents SET body = $1, version = version + 1WHERE id = $2 AND version = $3;             -- 0 rows: someone else updated first, reload and retry
09

Complexity and performance

Commit durability1 fsync of WAL

Group commit batches many transactions.

Lock waitContention dependent

Hot rows serialize access.

10

Trade-offs

Isolation vs throughput

Serializable prevents all anomalies but causes more aborts and retries; lower levels need explicit locks or checks.

Pessimistic vs optimistic

Locks suit high contention; optimistic version checks suit low contention and avoid blocking.

11

Variants and related techniques

Distributed transactions

Two-phase commit across databases, or sagas with compensation.

Savepoints

Partial rollback within a transaction.

12

Common mistakes

  • Calling external APIs inside a transaction.

    Fix: Holds locks for long periods; call external services before or after, and use an outbox for side effects.

  • Read-then-write without locks.

    Fix: Use atomic updates, FOR UPDATE, or version checks.

  • Not retrying serialization failures.

    Fix: Wrap transactions in retry logic for error codes like 40001.

13

Interview questions

How do you prevent two users from booking the same seat?

Use a transaction with SELECT ... FOR UPDATE on the seat row, or a conditional update that changes status only if it is still available, plus a unique constraint on (event_id, seat_no) for bookings.

What is write skew?

Two transactions read the same data, each makes a decision that is valid alone, and they write different rows, violating a rule together (for example, both doctors go off call). Serializable isolation or explicit locks prevent it.

14

Practice problems

ProblemDifficultyWhat it trains
Implement a safe money transferEasyAtomicity.
Design seat booking with holds and expiryMediumLocks and timeouts.
Design a double-entry ledgerHardInvariants and idempotency.