BEGIN, COMMIT and ROLLBACK
corebeginnerBEGIN starts a transaction block, grouping every following statement into one all-or-nothing unit. COMMIT makes every change in that block permanent and visible to other transactions. ROLLBACK discards every change made since BEGIN, as if none of it ever happened.
Think of it as
Think of BEGIN as opening a draft that only you can see, COMMIT as publishing the entire draft at once, and ROLLBACK as discarding the draft entirely. Nothing in between is visible to anyone else, and nothing is real until COMMIT actually runs — a crash, a ROLLBACK, or a disconnected client before COMMIT means every statement since BEGIN is undone, not just the last one.
What we're doing: Move money between two accounts inside a transaction, then show that a ROLLBACK undoes both statements as one unit, not just the most recent one.
- 2–3
- Both updates are part of the same transaction block — neither is committed yet.
- 7
- ROLLBACK discards BOTH updates as a single unit, not just the second one.
name | balance
-------+---------
Alice | 900
Bob | 1100
ROLLBACK
name | balance
-------+---------
Alice | 1000
Bob | 1000Why this works: The whole point of wrapping both UPDATEs in one transaction is that they succeed or fail together — a money transfer where only one side happened would leave the books wrong, and ROLLBACK demonstrates that guarantee concretely: undoing "the last statement" is not a thing PostgreSQL transactions do, only undoing the entire block since BEGIN.
Assuming each statement inside a transaction block commits independently
Wrong
Better
What you see: A client disconnects or crashes partway through a multi-statement transaction, and the developer is surprised to find NONE of the statements took effect — including the first one, which "looked done" when it ran.
Why: Nothing inside a transaction block is durable until COMMIT actually executes — an interrupted session, a crash, or an unhandled error before COMMIT means PostgreSQL rolls the entire block back automatically, since a transaction that never reached COMMIT was never meant to be permanent in the first place.
- No transaction (start)
- → Transaction block open when BEGIN
- Transaction block open
- → Committed when COMMIT
- → Rolled back when ROLLBACK
- Committed (end)
- Rolled back (end)
BEGIN / COMMIT / ROLLBACK
Remember: BEGIN opens an all-or-nothing block; COMMIT makes every change since BEGIN permanent at once; ROLLBACK discards every change since BEGIN, not just the last statement. Nothing is durable until COMMIT actually runs.
See also: atomicity and transaction boundaries · autocommit behavior

