2026-06-15
Every database isolation level except one promises that you'll only ever see committed data. Read Uncommitted breaks that promise. It lets one transaction see the in-flight, unwritten changes of another — and if that other transaction rolls back, you acted on data that never officially existed. This is the dirty read.
Here's the canonical example. Transaction A transfers $500 from Alice to Bob:
Alice had $1000 the whole time. B rejected her based on a balance that never existed. No error was thrown, no log line flagged it — B just silently made a wrong decision on phantom data.
Why does this isolation level even exist? Performance. Read Uncommitted skips read locks entirely, so readers never block on writers. In the 1990s, when row-level locking was expensive and MVCC was rare, this was a real throughput win. Today, most modern databases (Postgres, Oracle, SQL Server with snapshot isolation enabled) use MVCC, which gives you Read Committed for free — Read Uncommitted offers no benefit over Read Committed in Postgres at all (it silently upgrades).
Where it still bites people: MySQL with InnoDB honors Read Uncommitted literally. SQL Server defaults to Read Committed but developers add WITH (NOLOCK) hints "to make reports faster" — that's Read Uncommitted by another name. Reporting dashboards built this way can show numbers that briefly contradict themselves: a sum that doesn't equal its parts because rows were read mid-update.
Rule of thumb: if a decision will be persisted, side-effected, or shown to a user as authoritative, never read it under Read Uncommitted. The performance gain is typically under 5% on MVCC databases and the correctness cost is unbounded. Reserve it for one narrow case: approximate aggregates on monitoring dashboards where "roughly right, very fast" beats "exactly right, slightly slower" and the consumer understands the data is best-effort.
The deeper lesson: isolation levels are not just performance dials. Each one defines a precise set of anomalies you're choosing to tolerate. Dirty reads aren't just stale data — they're data that was never true. That's a fundamentally different category of bug, and one that won't appear in any audit log because nothing actually went wrong on the write side.
