46 BEGIN, COMMIT, ROLLBACK
A transaction groups statements into an all-or-nothing unit. BEGIN (or START TRANSACTION) starts one; COMMIT makes the changes permanent; ROLLBACK discards them. Outside a transaction, each statement runs in its own implicit one — PostgreSQL is always transactional, you just choose whether to name the boundaries. Transactions are how you keep your data consistent through multi-step changes.
What you’ll learn
- Starting a transaction with
BEGINand finishing withCOMMITorROLLBACK - The ACID properties (especially Atomicity and Isolation)
- Implicit per-statement transactions
- Isolation levels:
READ COMMITTED(default),REPEATABLE READ,SERIALIZABLE - The
ABORT/ “transaction is aborted” state
Example
PostgreSQL provides full ACID guarantees:
- Atomic: either every change in the transaction takes effect or none does.
- Consistent: constraints are checked; the database moves from one valid state to another.
- Isolated: concurrent transactions do not see each other’s uncommitted work (degrees of strictness vary by isolation level).
- Durable: with the normal durability settings, a successful
COMMITmakes logged changes survive a crash; settings such assynchronous_commit = offchange that guarantee.
The default isolation is READ COMMITTED: each statement sees a snapshot of the database at the moment it starts. REPEATABLE READ gives the whole transaction a single snapshot — repeated reads see the same data. SERIALIZABLE adds checks for serialization anomalies and can roll back transactions that would produce a non-serial schedule.
PostgreSQL’s transaction error model is strict: any error inside a transaction aborts the transaction. Subsequent statements fail with “current transaction is aborted, commands ignored until end of transaction block” until you ROLLBACK. To handle errors gracefully mid-transaction, use savepoints (next lesson).
This lesson deliberately inserts a duplicate primary key to demonstrate transaction failure. Run it with psql’s default ON_ERROR_STOP=off, so the following ROLLBACK and cleanup execute. Other lessons can use -v ON_ERROR_STOP=1.
Run the example
To run:
Common pitfalls
- Forgetting to
COMMITin interactive psql means everything you did is rolled back when you disconnect. Set\set AUTOCOMMIT offif you want explicit control; the defaultAUTOCOMMIT onruns each statement in its own implicit transaction. - Long-running transactions hold row locks and prevent autovacuum from reclaiming dead tuples. Keep transactions short.
- Mixing schema changes (DDL) and data changes (DML) in one transaction is fine in PostgreSQL — unlike MySQL, DDL is transactional too.
- In
READ COMMITTED, two statements in the same transaction can see different values of the same row (if a concurrent transaction committed between them). For consistent multi-statement reads, switch toREPEATABLE READ.
BEGIN; ... ROLLBACK; can undo transactional table changes during a rehearsal, but it still takes locks and runs triggers. Sequence increments and external side effects are not rolled back. Use a disposable database for these exercises.
The script drops tx_demo during cleanup. First recreate it with CREATE TABLE tx_demo (id integer PRIMARY KEY, val text); INSERT INTO tx_demo VALUES (1, 'a');. Then open two psql sessions. In session A: BEGIN; UPDATE tx_demo SET val = 'x' WHERE id = 1; (do not commit yet). In session B: SELECT * FROM tx_demo; — you should see the old value. Then session A COMMIT; and session B’s next SELECT will see the new value.
Downloads
SQL file: begin-commit-rollback.sql · All lesson files · Setup guide