🔁BEGIN, COMMIT, ROLLBACK
Transactions are atomic story arcs
A transaction wraps a set of statements into one unit: succeed together or leave no trace (modulo isolation quirks readers observe). Autocommit turns every standalone statement into its own tiny arc, great for ad-hoc queries, risky for multi-step business invariants.
Explicit boundaries
BEGIN … COMMIT. Application frameworks often map one HTTP request to one transaction, know your default.ROLLBACK is not shame
Happy path: explicit transaction
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;| step |
|---|
| BEGIN |
| UPDATE 1 row |
| UPDATE 1 row |
| COMMIT |
Abort path: rollback discards everything
BEGIN;
INSERT INTO transfers (from_id, to_id, amt) VALUES (1, 2, 500);
-- application detects insufficient funds
ROLLBACK;| state |
|---|
| no rows persisted |
Long transactions holding locks
Starting a txn, calling slow external APIs, then updating rows pins locks and stalls everyone else, p99 latency explodes.
Pattern: shorten critical sections
Do network I/O first, then open the txn, mutate, commit quickly. For cross-service flows, use sagas with outbox patterns instead of one giant DB txn.
Savepoints
SAVEPOINT lets you partially roll back nested units inside one transaction, handy for complex stored procedures, but easy to misuse without clear naming and documentation.
Driver defaults
Autocommit wraps each standalone statement in its own transaction; DDL may issue implicit commits on many engines. Document session defaults next to deployment configs so on-call does not guess.
TL;DR
BEGIN (or START TRANSACTION) opens a unit of work; COMMIT makes durable what succeeded; ROLLBACK discards uncommitted changes. Savepoints add nested rollback points on some engines. Drivers often default to autocommit, explicit transactions are required for multi-statement invariants (transfers, inventory). Know DDL auto-commit rules on your database.