Last modified: March 23, 2026
This article is written in: πΊπΈ
Database transactions are a cornerstone of reliable data management. They let an application bundle multiple low-level reads and writes into a single, all-or-nothing unit so the database moves cleanly from one consistent state to anotherβeven when dozens of users race to change the same rows or hardware glitches interrupt the process. Transactions offer the developer a simple success/ failure switch while the engine handles locking, logging, versioning, and recovery behind the scenes.
| Application (Transaction Context) |
| |
| BEGIN TRANSACTION βββΊ Perform SQL/CRUD Operations |
| |
| COMMIT βββ Success? ββββββ Yes ββββ |
| β |
| ROLLBACK βββ On error or cancel ββββ |
+-------------------------------------------------------------+
A typical flow starts with BEGIN (or an implicit start), runs several statements that may touch many tables, then finishes with COMMIT to make every change permanentβor ROLLBACK to annul them if any step fails.
-- Basic transaction: transfer $200 between accounts (PostgreSQL)
BEGIN;
UPDATE accounts SET balance = balance - 200 WHERE id = 1;
UPDATE accounts SET balance = balance + 200 WHERE id = 2;
COMMIT;
-- Explicit error handling with savepoints
BEGIN;
INSERT INTO orders (customer_id, total) VALUES (42, 99.95);
SAVEPOINT before_inventory;
UPDATE inventory SET qty = qty - 1 WHERE product_id = 7;
-- If the update fails (e.g., CHECK constraint: qty >= 0):
ROLLBACK TO before_inventory;
-- Retry with a different fulfilment path
INSERT INTO backorders (product_id, customer_id) VALUES (7, 42);
COMMIT;
-- Setting an isolation level for a critical read
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN;
SELECT balance FROM accounts WHERE id = 1;
UPDATE accounts SET balance = balance - 50 WHERE id = 1;
COMMIT;
UPDATE fails the entire transaction rolls back and no money is lost.Isolation levels control how much of one transaction's uncommitted work is visible to others. Moving from the weakest to the strongest level trades concurrency for correctness.
Isolation Level Anomaly Spectrum
READ READ REPEATABLE SERIALIZABLE
UNCOMMITTED COMMITTED READ
ββββββββββββββΊβββββββββββββββΊβββββββββββββββββββΊβββββββββββββββββββΊ
β β β β
β Dirty Reads β β β
β Non-Repeat. β Non-Repeat. β β
β Phantoms β Phantoms β Phantoms β (no anomalies)
β β β β
βββ Fastest ββββββββββββββββββββββββββββββ Slowest / Safest βββΊ
SELECTs in the same transaction can return different rows if another transaction commits between them (non-repeatable read).
| Level | Dirty Read | Non-Repeatable Read | Phantom Read | Typical Default In |
| READ UNCOMMITTED | Possible | Possible | Possible | β |
| READ COMMITTED | β | Possible | Possible | PostgreSQL, Oracle, SQL Server |
| REPEATABLE READ | β | β | Possible | MySQL / InnoDB |
| SERIALIZABLE | β | β | β | Selected explicitly |
Single-Object Write Flow
+-------------------------+
| BEGIN |
+-------------+-----------+
|
v
+-------------------------+
| Lock / Version Check |
+-------------+-----------+
|
v
+-------------------------+
| Apply the Write |
+-------------+-----------+
|
v
+-------------------------+
| COMMIT or ROLLBACK |
+-------------------------+
Write-Ahead Logging (WAL) Flow
Client WAL (on disk) Data Pages (on disk)
β β β
β 1. BEGIN + UPDATE row 42 β β
βββββββββββββββββββββββββββΊ β β
β β β
β 2. Append redo β
β log entry βββΊ [LSN 101: row 42 β
β old=A, new=B] β
β β β
β 3. COMMIT β β
βββββββββββββββββββββββββββΊ β β
β 4. fsync commit β
β record to disk β
β βββ 5. ACK ββββββββββββ β β
β β β
β β 6. Checkpoint β
β β (lazy background write) β
β ββββββββββββββββββββββββΊ β
β β Data page updated β
Complex workloads touch many independent resourcesβmultiple tables, shards, or even distinct databasesβso additional coordination layers are required.
Coordinator Participant(s)
βββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ
β 1. PREPARE β β Receive PREPARE β
β (Ask participants to vote) β βββββΊ β Validate / Pre-commit β
βββββββββββββββββββββββββββββββββ β β
β² β Send VOTE (YES / NO) β
β βββββββββββββββββ¬βββββββββββββββββ
β β
ββββββββββββββββ 2. VOTES ββββββββββββββββββββ
Decision Phase
β
βΌ
βββββββββββββββββββββββββββ
β 3. DECISION β
β β
β All YES β COMMIT β
β Any NO β ROLLBACK β
βββββββββββββββββββββββββββ
Deadlock Example
Transaction A Transaction B
| |
lock X lock Y
| |
wait Y βββββββββββββββ wait X
| |
(circular wait β deadlock)
Savepoints let you mark intermediate positions inside a running transaction so you can roll back to that point without aborting the entire transaction.
Savepoints within a Transaction
BEGIN
β
βββ INSERT INTO orders ...
β
βββ SAVEPOINT sp1 βββββββββββββββββ mark
β β
β βββ UPDATE inventory ...
β β
β βββ (error) β ROLLBACK TO sp1 βββ partial undo
β
βββ INSERT INTO backorders ... βββ continue normally
β
βββ COMMIT βββ everything except
the rolled-back part
ROLLBACK TO replays undo records back to that point.RELEASE SAVEPOINT sp1 discards the marker without rolling back, freeing engine resources.
| Method | Underlying Mechanism | Pros | Cons | Typical Scenarios |
| Locks | Pessimistic read/write locks | Strong consistency; simple mental model | Blocking, deadlocks, lock-escalation overhead | OLTP systems where conflicts are frequent |
| MVCC | Append row versions + snapshot reads | Readers never block writers; high read scalability | Vacuuming/garbage collection; more I/O for version churn | Mixed read-heavy workloads (PostgreSQL, InnoDB) |
| Timestamps | Assign global time/order to Txns | Easy to serialize logically; no blocking | High abort rate if contention; clock or logical-counter drift | In-memory or distributed DBs (Spanner, FoundationDB) |
| Optimistic | Validate at commit (compareβandβswap) | Near-zero overhead during read phase; suits low contention | Late failures waste work; write-write conflicts cause retries | Microservices or mobile apps with rare collisions |