Module P-3·21 min read

BEGIN, COMMIT, ROLLBACK, isolation levels, and safe atomic operations — what every production application must understand.

JJS
Written by Jatin Jain Saraf · Senior Software Engineer

P-3 — Transactions and ACID in Practice

Who this module is for: You can write queries and design schemas. Now you need to understand how to group multiple operations into an atomic unit — so that either all of them succeed or none of them do. This is the mechanism that prevents your application from leaving the database in a half-updated, inconsistent state.


The Problem Transactions Solve

Imagine a bank transfer: debit $100 from Alice, credit $100 to Bob.

sql

What happens if the server crashes, the network drops, or an error occurs between the two statements? Alice has lost $100 and Bob never received it. The money has vanished.

Transactions prevent this by grouping operations: either both updates happen, or neither does.


BEGIN, COMMIT, ROLLBACK

sql

If anything goes wrong between BEGIN and COMMIT:

sql

Without a BEGIN, every statement is its own transaction — it auto-commits immediately. This is fine for isolated statements, but dangerous for multi-step operations.

With a BEGIN, nothing is visible to other connections until COMMIT. If the session disconnects before COMMIT, PostgreSQL automatically rolls back the transaction.


ACID: What It Actually Means

A — Atomicity: All operations in a transaction succeed, or none do. There is no partial success.

sql

C — Consistency: A transaction brings the database from one valid state to another. Constraints (NOT NULL, FOREIGN KEY, CHECK) are enforced at commit time.

sql

I — Isolation: Transactions run as if they are the only transaction in the system. Other transactions' uncommitted changes are invisible.

sql

D — Durability: Once committed, changes survive crashes. PostgreSQL's Write-Ahead Log (WAL) ensures this.


Isolation Levels in Practice

The SQL standard defines four isolation levels; PostgreSQL accepts all four names but only implements three distinct behaviors — READ UNCOMMITTED is accepted syntactically and silently mapped to READ COMMITTED (Postgres never does dirty reads). The default, and the one you will use for almost everything, is READ COMMITTED.

READ COMMITTED (default)

Each query in a transaction sees a fresh snapshot of committed data at the time that query starts. This means a transaction can see different data at the beginning vs. the end if other transactions commit in between.

sql

This is acceptable for most application reads. Each query gets a consistent view; the transaction as a whole does not.

REPEATABLE READ

The entire transaction sees the same snapshot of data as of when the transaction started. New inserts/updates by other transactions are invisible for the duration.

sql

Use this when your transaction needs a consistent view across multiple queries — for example, generating a report where all queries must see the same data point in time.

SERIALIZABLE

The strongest level. Transactions execute as if they were serialised one after another. PostgreSQL detects situations where concurrent transactions could produce results different from any serial execution and fails one of them.

sql

Use this sparingly — it adds overhead and can cause transaction failures that need retrying.

Rule for most applications: use the default READ COMMITTED. Move to REPEATABLE READ only when you need a consistent multi-query snapshot. Use SERIALIZABLE only for complex financial operations where non-serialisable anomalies are a real risk.


SAVEPOINT — Partial Rollback

Sign in to keep reading

The rest of this module is free — sign in with Google to unlock it and track your progress.

Sign in & Register

Discussion

0

Join the discussion

Loading comments...

© 2026 Jatin Jain Saraf (JJS). All rights reserved.