Managing SQL Transactions

1. Starting Transactions

CommandUse
BEGIN / START TRANSACTIONStart explicit tx
SET TRANSACTION ISOLATION LEVEL ...Configure before first statement
READ ONLY / READ WRITEAccess mode hint
DEFERRABLE (PG)Wait for serializable snapshot

2. Committing Changes

CommandEffect
COMMITPersist all changes; release locks
COMMIT AND CHAINCommit and start new tx immediately
2-Phase CommitPREPARE TRANSACTION 'id'; COMMIT PREPARED 'id';

3. Rolling Back Changes

CommandEffect
ROLLBACKDiscard all changes since BEGIN
ROLLBACK TO SAVEPOINT sUndo to savepoint, tx continues
ROLLBACK AND CHAINRollback + new tx
Implicit rollbackOn disconnect or fatal error

4. Creating Savepoints

Example: SAVEPOINT

BEGIN;
INSERT INTO orders(...) VALUES (...);
SAVEPOINT before_items;
INSERT INTO order_items(...) VALUES (...);
-- something goes wrong with items
ROLLBACK TO SAVEPOINT before_items;
COMMIT;  -- order committed, items not
CommandDetail
SAVEPOINT nameMark point inside tx
RELEASE SAVEPOINT nameDiscard the savepoint marker
ROLLBACK TO nameUndo to that point

5. Understanding ACID Properties

PropertyGuarantee
AtomicityAll-or-nothing
ConsistencyValid → valid state per constraints
IsolationConcurrent txs appear serial (per level)
DurabilityCommitted survives crash (via WAL)

6. Setting Isolation Levels

LevelPreventsAllows
READ UNCOMMITTEDDirty, non-repeatable, phantom reads
READ COMMITTEDDirty readsNon-repeatable, phantom
REPEATABLE READDirty, non-repeatablePhantom (PG: also phantom)
SERIALIZABLEAll anomalies
Note: Postgres default is READ COMMITTED; MySQL InnoDB default is REPEATABLE READ. Postgres RR provides snapshot isolation; SERIALIZABLE adds SSI (predicate detection).

7. Handling Concurrency Issues

AnomalyDescription
Dirty ReadRead uncommitted changes
Non-repeatable ReadSame row, different values on re-read
Phantom ReadSame query, different row set on re-read
Lost UpdateTwo writes, one overwrites the other
Write SkewTwo txs read overlapping set, write disjoint sets, violating invariant

8. Using Optimistic Locking

MechanismDetail
Version columnWHERE id=? AND version=? then bump
TimestampWHERE updated_at=?
Hash checkCompare row hash before write
Result0 rows updated → retry / merge / fail

Example: Optimistic Lock

UPDATE accounts SET balance = ?, version = version + 1
WHERE id = ? AND version = ?;
-- if rowcount = 0, someone else updated → retry

9. Using Pessimistic Locking

LockSyntax
Row lock (exclusive)SELECT ... FOR UPDATE
Row lock (shared)SELECT ... FOR SHARE
Skip lockedFOR UPDATE SKIP LOCKED — queue patterns
No waitFOR UPDATE NOWAIT — fail-fast
Table lockLOCK TABLE t IN MODE ...
Advisory lock (PG)pg_advisory_lock(id)

10. Managing Deadlocks

StrategyDetail
Consistent lock orderAlways acquire keys in same order (e.g., ascending id)
Short transactionsReduce window for contention
Detect & retryDB rolls back one victim; app catches SQLSTATE 40P01 / 1213
Lock timeoutSET lock_timeout = '5s';
Reduce isolationREAD COMMITTED has fewer lock conflicts
Warning: Deadlocks are inevitable in concurrent systems — always implement automatic retry with exponential backoff.