Skip to main content

Transactions, Concurrency and Indexing

Transactions and ACID​

A transaction is a logical unit of work.

transfer.sql
BEGIN;
UPDATE account SET balance = balance - 500 WHERE id = 1;
UPDATE account SET balance = balance + 500 WHERE id = 2;
COMMIT; -- or ROLLBACK on error
PropertyMeaning
AtomicityAll or nothing
ConsistencyMoves the database from one valid state to another
IsolationConcurrent transactions do not see each other's partial work
DurabilityCommitted changes survive crashes (write-ahead log)

Concurrency problems​

ProblemDescription
Dirty readReading uncommitted data
Non-repeatable readThe same row read twice returns different values
Phantom readA repeated query returns new rows
Lost updateTwo writers overwrite each other

Isolation levels (SQL standard)​

LevelDirty readNon-repeatablePhantom
Read UncommittedPossiblePossiblePossible
Read CommittedNoPossiblePossible
Repeatable ReadNoNoPossible
SerializableNoNoNo

Concurrency control​

  • Locking: shared (read) and exclusive (write) locks; two-phase locking (2PL) guarantees serializability but can deadlock.
  • Timestamp ordering and MVCC (multi-version concurrency control): readers see a snapshot and do not block writers (PostgreSQL, MySQL InnoDB).

A schedule is serializable if it is equivalent to some serial order; conflict serializability is tested with a precedence graph (a cycle means not serializable).

Indexing​

An index is a separate structure that speeds up lookups at the cost of extra storage and slower writes.

index.sql
CREATE INDEX idx_student_city ON student (city);

EXPLAIN SELECT * FROM student WHERE city = 'Pune'; -- check it is used
Index typeNotes
B+ treeDefault; supports equality and range queries, keeps data sorted
HashEquality only
ClusteredDetermines the physical row order (one per table)
Non-clusteredSeparate structure pointing to rows
CompositeMulti-column; follows the left-most prefix rule
NOTE

Indexes help WHERE, JOIN and ORDER BY columns, but not queries that wrap the column in a function (WHERE LOWER(city) = 'pune') unless a matching functional index exists.