4.4.18 · D1Databases

Foundations — Concurrency anomalies — dirty read, non-repeatable read, phantom read

1,686 words8 min readBack to topic

This page assumes nothing. If the parent note said " reads a row that modified but has not committed", then by the end of this page you will know exactly what every word in that sentence means — as a picture, not a phrase.


Symbol 0 — A "row" and a "table"

Look at the figure below. The whole grid is the table accounts. The one highlighted horizontal strip is a row — the account with id = 1. Everything in this topic is about who is looking at that strip, and when.

Figure — Concurrency anomalies — dirty read, non-repeatable read, phantom read

Symbol 1 — , : transactions as timelines

The picture that matters: draw each transaction as its own horizontal timeline, left = earlier, right = later. Time flows the same way for both, so we stack the timelines and read them together.

Figure — Concurrency anomalies — dirty read, non-repeatable read, phantom read
Read T1 ::: What does the "1" in mean?
Just a label — "transaction number one". It names which concurrent actor we are talking about; it carries no maths.

Symbol 2 — READ and WRITE (SELECT / UPDATE / INSERT / DELETE)


Symbol 3 — COMMIT and ROLLBACK

The figure shows the pencil-vs-ink idea on a single balance value.

Figure — Concurrency anomalies — dirty read, non-repeatable read, phantom read
What state is a write in before COMMIT?
Uncommitted (provisional / "in pencil") — it may still vanish on ROLLBACK.
What does ROLLBACK do to every write of a transaction?
Erases them all, as if the transaction never ran.

Symbol 4 — "concurrent" and the interleaving


Symbol 5 — a "range" or "predicate" ( WHERE age > 30 )

Picture the predicate as a net dropped over the grid: every row that satisfies the condition is caught in the net; the rest fall through.

Figure — Concurrency anomalies — dirty read, non-repeatable read, phantom read
The row is caught by the net because...
its column value satisfies the WHERE condition (the predicate). It's a member of the result set.

How these foundations feed the topic

Row and Table

Transaction T1 T2

Read and Write verbs

Commit and Rollback

Concurrent overlap

Predicate net WHERE

Concurrency anomalies

Dirty read uses Commit and Rollback

Non repeatable uses UPDATE

Phantom uses INSERT DELETE and Predicate

Isolation Levels fix them

Each arrow means "you must understand the left box to picture the right box". Notice the two writes-branches (UPDATE vs INSERT/DELETE) and the predicate net all feed the anomalies separately — that is why there are exactly three distinct glitches, not one.


Where each foundation is used by the parent

Recall Foundation → which anomaly it unlocks
  • Row/table → lets us say "reads a row".
  • / timelines → lets us say " acts between 's two reads".
  • UPDATE (write-inside) → non-repeatable read.
  • INSERT/DELETE (write-count) → phantom read.
  • Commit/rollback (pencil/ink) → dirty read.
  • Predicate net → phantom read + the range locks in Isolation Levels.

For the medicine — how Isolation Levels, Locking — Shared and Exclusive Locks, MVCC — Multiversion Concurrency Control, Two-Phase Locking (2PL) and the safety guarantees of ACID Properties switch these glitches off — head back to the parent topic. (Beware: cranking isolation too high can cause Deadlocks — a different problem, not an anomaly.)


Equipment checklist

Test yourself — you are ready for the parent topic once every reveal matches your own words.

A "row" is
one horizontal strip of a table's grid — one real-world record.
and are
two concurrent transactions (all-or-nothing bundles of reads/writes); the subscript is just a name.
A READ (SELECT) does what to data
only looks — changes nothing.
The three WRITE verbs are
UPDATE (change inside a row), INSERT (add a new row), DELETE (remove a row).
"Uncommitted" means
written provisionally ("in pencil"), visible only within its own transaction, and possibly about to be erased.
COMMIT vs ROLLBACK
COMMIT makes all writes permanent (pencil → ink); ROLLBACK erases all of the transaction's writes.
"Concurrent" means
two transactions' timelines overlap — neither finished before the other started.
Why anomalies need overlap
without overlap one transaction can't see the other's draft, so no glitch is possible.
A "predicate" / WHERE condition is
a net that catches exactly the rows matching a condition — its catch is the result set.
Which write changes a row's value vs the set of rows
UPDATE changes a value (→ non-repeatable); INSERT/DELETE change the set (→ phantom).