What is a transaction?
A transaction groups several statements into one unit of work that either fully happens or fully doesn't — the engine-neutral theory, ACID and what each letter promises, lives in Concepts: what is a transaction?. This page is PostgreSQL keeping the promise.
How to read the demos
Each lesson shows a transcript generated from an actual run of the lesson's scenario (sessions A, B, … are separate PostgreSQL connections). How the scenarios work — and why the transcripts can't drift from reality — is explained in What this is
Atomicity, demonstrated
Session A transfers 150 from alice (who has only 100) to bob. The credit to bob succeeds; the debit from alice violates a CHECK constraint. Watch what happens to bob's already-successful credit:
A transfers 150 from alice to bob. Crediting bob works fine…
A> BEGIN;
BEGIN
A> UPDATE accounts SET balance = balance + 150 WHERE owner = 'bob';
UPDATE 1
B> SELECT balance FROM accounts WHERE owner = 'bob'; -- B can't see A's uncommitted credit
balance
---------
50
(1 row)…but debiting alice violates the CHECK constraint — she only has 100.
A> UPDATE accounts SET balance = balance - 150 WHERE owner = 'alice'; -- check_violation
ERROR: 23514: new row for relation "accounts" violates check constraint "accounts_balance_check"The failed transaction can only be rolled back. Bob's credit — which had succeeded — evaporates with it.
A> ROLLBACK;
ROLLBACK
B> SELECT owner, balance FROM accounts ORDER BY id;
owner | balance
-------+---------
alice | 100
bob | 50
(2 rows)Verified against PostgreSQL 18.4 · Run it yourself · Scenario source
A failed statement doesn't only fail itself, it dooms the whole transaction: nothing in it can ever commit, and your only move is to roll back — fully, or to a savepoint. Notice too that B never saw the half-finished transfer; it read bob's old balance while the credit was still in flight. What other sessions see of your in-flight work, and exactly when, is the entire subject of isolation levels.