Hook: Interviewers love this topic because isolation levels are where a database stops being a simple spreadsheet and starts acting like a busy restaurant kitchen.
Question: What are isolation levels in SQL transactions?
Answer: Isolation levels decide how much one transaction can see of another transaction’s uncommitted or recently committed work. In simple words, they control whether readers see a stable view of the data or a more current but less protected view. Higher isolation gives stronger correctness but usually less concurrency, which means more blocking or more retries.
Interview-Ready Answer: I’d say isolation levels are the rules that control what one transaction can observe while other transactions are running. The main trade-off is correctness versus throughput: low isolation allows more concurrency but can expose anomalies like dirty reads or non-repeatable reads, while strong isolation like serializable gives the safest behavior but can block more or force transaction retries. A good practical detail is that many databases default to READ COMMITTED, while MySQL InnoDB often defaults to REPEATABLE READ.
Think of each transaction as a person reading and writing notes in a shared notebook. Isolation decides whether they can see someone else’s half-written notes, whether the page can change between two reads, and whether a summary query can suddenly include new rows.
The classic anomalies are:
READ COMMITTED or SERIALIZABLE.READ COMMITTED, each statement usually sees the latest committed data at the moment that statement begins.REPEATABLE READ, the whole transaction typically sees one stable snapshot, so repeated reads return the same committed version.SERIALIZABLE, the database tries to make concurrent transactions behave as if they ran one after another. If that is not possible, it may abort one transaction with a serialization error so you can retry safely.| Level | Dirty read | Repeatable read | Phantoms | Typical note |
|---|---|---|---|---|
| Read Uncommitted | Possible | No | No | Rarely useful |
| Read Committed | No | No | No | Common default |
| Repeatable Read | No | Yes | Often no | Snapshot style |
| Serializable | No | Yes | Yes | Strongest safety |
Important dialect gotcha: PostgreSQL accepts READ UNCOMMITTED, but it behaves like READ COMMITTED. Also, MySQL InnoDB’s REPEATABLE READ is stronger than many people expect because it uses extra locking to reduce phantoms.
READ COMMITTED for most OLTP work, like user profiles or order history, where fresh data matters and occasional re-reading is acceptable.REPEATABLE READ when a transaction must work from one stable snapshot, such as building a monthly report.SERIALIZABLE when correctness is critical, such as money movement, inventory reservation, or enforcing a business rule that spans multiple rows.There is no meaningful Big-O complexity number for isolation levels. In practice, lower isolation usually means fewer locks and fewer retries, so it scales better under contention. Higher isolation can increase lock waits, row-version checks, memory use for snapshots, and aborted transactions that must be retried. A useful interview phrase is: stronger isolation shifts cost from wrong answers to slower or retried work.
SERIALIZABLE does not mean zero failures; it often means the database may reject a transaction and ask you to retry.Scenario: a flash-sale checkout service for an e-commerce app.
Two users click Buy at almost the same time for the last item in stock. If the checkout transaction reads stock, then writes a decrement, and the isolation is too weak, both requests can see stock 1 and both try to reserve it. The result is overselling, angry users, and a support flood.
What goes wrong: the database log may show lock waits, deadlocks, or serialization failures; the application may show a confusing mix of succeeded payments and failed shipments. Users see messages like item sold out after payment, or the order count in admin dashboards does not match the warehouse count. In a stronger isolation design, the app either blocks one checkout briefly or retries a transaction cleanly instead of silently corrupting inventory.
Mental model: the database is the bouncer at the door; isolation levels decide how tightly it checks who can peek at the guest list while changes are happening.
-- PostgreSQL demo: isolation levels in action
-- This script is intentionally simple and runnable as-is.
-- It shows the current isolation level, uses a savepoint as an edge case,
-- and highlights where concurrency would matter in a real second session.
DROP TABLE IF EXISTS account_demo;
CREATE TABLE account_demo (
id integer PRIMARY KEY,
balance integer NOT NULL CHECK (balance >= 0)
);
INSERT INTO account_demo (id, balance)
VALUES (1, 100), (2, 100);
-- READ COMMITTED: each statement sees the latest committed data when that statement starts.
BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT current_setting('transaction_isolation') AS isolation_level,
SUM(balance) AS total_balance
FROM account_demo;
COMMIT;
-- REPEATABLE READ: the whole transaction uses one stable snapshot.
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT current_setting('transaction_isolation') AS isolation_level,
COUNT(*) AS rows_seen
FROM account_demo;
-- Edge case: if you make a mistake inside the transaction,
-- a savepoint lets you undo only the bad step instead of losing the whole transaction.
SAVEPOINT before_insert;
INSERT INTO account_demo (id, balance) VALUES (3, 50);
ROLLBACK TO SAVEPOINT before_insert;
SELECT COUNT(*) AS rows_seen_after_rollback
FROM account_demo;
COMMIT;
-- SERIALIZABLE: strongest isolation. In real concurrent traffic, one of two conflicting
-- transactions may fail with a serialization error and should be retried by the app.
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT current_setting('transaction_isolation') AS isolation_level,
COUNT(*) AS rich_accounts
FROM account_demo
WHERE balance >= 100;
COMMIT;
SELECT *
FROM account_demo
ORDER BY id;Follow-up & Tricky Questions:
READ COMMITTED, MySQL InnoDB often REPEATABLE READ, and SQL Server commonly READ COMMITTED.REPEATABLE READ always stop phantom reads? Not universally. It depends on the database engine; some use extra locks, some use snapshots, and some still need serializable to fully prevent phantoms and write skew.READ UNCOMMITTED always faster? Not necessarily. It can still contend on writes, and many systems do not truly expose dirty reads in the way people assume.Common Mistakes:
Memory Hook: Isolation is the restaurant rule for shared plates: do you see half-cooked food, the final plated dish, or only a single frozen photo of the kitchen? That picture helps you remember READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, and SERIALIZABLE from weakest to strongest.
Cheat Sheet:
READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE.Practice Tasks:
READ COMMITTED plus locks or SERIALIZABLE plus retries.