Schedules, Serializability, VSR & CSR
The five anomalies concurrency can produce, and the two formal notions of correctness that rule them out — view-serializability and conflict- serializability. The conflict graph, the class hierarchy, and the exam instruction that makes it all pay off: use class inclusion wherever possible.
01 · Motivation
The five anomalies
Concurrency exists because serial execution wastes the machine: hundreds of transactions per second cannot each wait for the previous one’s disk I/O. The price is that interleaving can produce states no serial execution ever would.
There are exactly five, and each has a signature read/write pattern worth memorising — exam answers often need the name, and the name follows from the pattern.
1 · Lost update
Two transactions read the same value before either writes, so the second write is computed from
a stale state and overwrites the first. Starting from D = 100, +3 and +6 should give 109;
the interleaving gives 106.
Pattern: r1 r2 w2 w1 — the two reads precede both writes.
2 · Dirty read
A transaction reads a value written by another that has not yet committed — and then that transaction aborts. The value read never officially existed.
Pattern: r1 w1 r2 abort1 w2
3 · Nonrepeatable read
A transaction reads the same object twice and gets different values, because somebody wrote to it in between.
Pattern: r1 r2 w2 r1
4 · Phantom update
A transaction reads several objects tied by a constraint; another updates some of them in a way that is legal for itself but breaks the invariant the first was relying on.
Pattern: r1 r2 w2 r1
5 · Phantom insert
A transaction re-runs a query and gets a row that did not exist before — inserted by somebody else and satisfying its predicate.
Pattern: r1 w2(new data) r1
The fourth deserves its own worked look, because it is the one whose “victim” did nothing wrong. Take the constraint , with , , :
T1: r(A)=50, r(B)=30 T1 has seen 80 so far
T2: r(B)=30, r(C)=20
T2: B := 40, C := 10 T2 preserves the sum: 50+40+10 = 100
T2: w(B), w(C)
T1: r(C)=10 T1 now computes 50+30+10 = 90T2’s update is entirely legal — it does not change the total. T1 nevertheless observes a total of 90,
because it read B before and C after. To T1 it looks as though somebody else broke the invariant;
to T2 nothing is wrong. That is the anomaly.
Phantom insert is not about data that already exists
The distinguishing feature is that the offending row is created after the first
read. That matters enormously for the cure: locking existing rows cannot help, because there is
nothing yet to lock. Chapter 6’s predicate locks exist for exactly this case, and it is
why the SQL isolation level REPEATABLE READ still permits phantom inserts.
Two of these — the fourth and the fifth — are called phantoms precisely because the interfering change is invisible at the level of the individual objects the first transaction touched.
02 · Model
Schedules: the model
To reason precisely we strip transactions down to their reads and writes, and drop the program variables entirely.
An operation is a read or write of a specific object by a specific transaction: , . Operations differ if the transaction differs or the object differs — and are different operations, and so are and .
A schedule is a sequence of operations performed by concurrent transactions that respects the order of operations within each transaction. Given
T1: r1(x) w1(x)
T2: r2(z) w2(z)a schedule may interleave them any way that keeps before and before . How many are there? For transactions where has operations:
counts the permutations of whole transactions; counts the interleavings of all operations, divided by the orderings that would violate each transaction’s internal sequence. For the two transactions above, and — of which two are serial, and the rest are interleaved or nested. As transactions grow, : almost every schedule is interleaved, which is why we need a test rather than an enumeration.
In a serial schedule, each transaction’s actions occur in one contiguous block. In a serializable schedule, the database ends in the same state as it would under some serial schedule of the same transactions — the universally accepted definition of correctness.
Two simplifying assumptions, both dropped later
The theory in this chapter assumes commit projection: transactions are observed a-posteriori and only committed ones are considered. It also assumes we can inspect the whole schedule before judging it. Both are false in a running system — aborts happen, and a scheduler must decide operation by operation. Section 6 opens that gap, and chapters 6 and 7 close it.
Different notions of equivalence give different classes of “correct” schedules, and they trade accuracy against the cost of checking. Two matter.
03 · Classes
View-serializability
The more permissive of the two. Two schedules are equivalent if every read sees the same value and the final state of every object comes from the same transaction.
Two definitions do the work:
- reads-from in schedule when precedes and no other falls between them.
- is a final write if it is the last write on in .
Two schedules are view-equivalent () when they have the same operations, the same reads-from relation, and the same final writes. A schedule is view-serializable if it is view-equivalent to some serial schedule of the same transactions; the class is VSR.
Mnemonically: every read sees the same value it would have seen, and every object ends up with the value the same transaction gave it.
S3: w0(x) r2(x) r1(x) w2(x) w2(z)
S4: w0(x) r1(x) r2(x) w2(x) w2(z) ← serial: T0, T1, T2
reads-from: r1(x) and r2(x) both from w0(x)
final writes: w2(x), w2(z)
⇒ S3 ≈V S4, so S3 ∈ VSRSwapping two reads changed nothing, because reads do not affect what anyone else sees.
Deciding VSR is NP-complete
Checking whether two given schedules are view-equivalent is polynomial. Deciding whether a schedule is in VSR is NP-complete, because in general you must consider the reads-from and final writes of every possible serial schedule — combinatorial in the number of transactions. This is precisely why the next section exists: we trade accuracy for a test we can actually run.
In practice, for exam-sized schedules with three or four transactions, you do not enumerate. You compute the reads-from set and the final writes, then look for a serial order compatible with them — and the freedom you exploit is almost always blind writes, writes not preceded by a read of the same object by that transaction. A blind write can often be slid past other operations without changing what anybody reads.
04 · Classes
Conflict-serializability and the conflict graph
A stricter equivalence that is cheap to decide — and the one every exam exercise actually runs.
Two operations and () are in conflict when they address the same object and at least one is a write. So there are read-write conflicts (–, –) and write-write conflicts (–); two reads never conflict.
Two schedules are conflict-equivalent () when they contain the same operations and every conflicting pair appears in the same order in both. A schedule is
conflict-serializable — class CSR — when it is conflict-equivalent to a serial schedule.
The payoff is a decidable test:
The conflict-graph theorem
Build the conflict graph: one node per transaction, and an arc from to whenever some operation of conflicts with, and precedes, an operation of .
A schedule is in CSR if and only if its conflict graph is acyclic.
The practical recipe — and the one to use under exam pressure — is to project the schedule onto each object first, because conflicts only ever arise within one object’s projection:
1 · Project onto each object
Write out, per object, the operations touching it in schedule order. For S10 = w0(x) r1(x) w0(z) r1(z) r2(x) w0(y) r3(z) w3(z) w2(y) w1(x) w3(y):
x: w0 r1 r2 w1 · y: w0 w2 w3 · z: w0 r1 r3 w3
2 · Read the arcs off each projection
Within x: w0 conflicts with r1, r2 and w1 → arcs T0→T1, T0→T2, T0→T1; r1 and r2 both conflict
with w1 → T1→T1 (ignore, same transaction) and T2→T1. Within y: T0→T2, T0→T3, T2→T3. Within
z: T0→T1, T0→T3, T1→T3.
3 · Check acyclicity
Collected arcs: T0→T1, T0→T2, T0→T3, T2→T1, T2→T3, T1→T3. No cycle, so S10 ∈ CSR.
4 · Read the serialization order off the graph
Any topological order of an acyclic conflict graph is a conflict-equivalent serial schedule. Here T0 < T2 < T1 < T3 works. There may be several — every total order compatible with the partial order is a valid answer, and exams that say “list all the possible equivalent serial schedules” want all of them.
Deep dive Why acyclicity is exactly the right test
Both directions are short enough to reproduce, and August 2024 asked for the reasoning explicitly.
CSR ⇒ acyclic. Let be in CSR. Then it is conflict-equivalent to some serial schedule; relabel the transactions so that serial order is . Because the serial schedule has every conflicting pair in the same order as , every arc in ‘s conflict graph runs from a lower index to a higher one. A cycle would require at least one arc with . So there is no cycle.
Acyclic ⇒ CSR. An acyclic graph induces a topological ordering of its nodes — an order in which every arc points forward. Take any serial schedule whose transactions follow that order. For every conflicting pair the arc says precedes , and the serial schedule agrees; so the serial schedule is conflict-equivalent to , and CSR.
The second direction is also the constructive one: it is how you produce the serial schedule the exam asks you to exhibit.
05 · Classes
The class hierarchy, and how the exam wants you to use it
CSR is strictly contained in VSR. Knowing the direction of that containment — and the ones that follow in chapters 6 and 7 — converts one verdict into five.
Every conflict-serializable schedule is view-serializable, and the proof is two lines. Suppose . They must have the same final writes, since otherwise two writes would appear in different orders and writes conflict. They must have the same reads-from relations, since otherwise some conflicting pair would appear in a different order. Hence .
The converse fails, and the standard counter-example is worth memorising:
S = r1(x) w2(x) w1(x) w3(x)
view-equivalent to the serial T1 T2 T3 = r1(x) w1(x) w2(x) w3(x)
reads-from: r1(x) reads the initial value in both
final write: w3(x) in both ⇒ S ∈ VSR
but not conflict-serializable:
r1(x) before w2(x) ⇒ T1 → T2
w2(x) before w1(x) ⇒ T2 → T1 ⇒ cycle, S ∉ CSRThe gap is created entirely by blind writes. w2(x) is blind — T2 never read x — so nobody
observes the value it wrote, and it can be reordered freely under view equivalence while conflict
equivalence, which looks only at operation types, forbids it. With no blind writes anywhere, VSR and
CSR coincide.
The full picture, with the classes chapters 6 and 7 add:
with the timestamp classes branching off separately (chapter 7 shows TS ⊂ CSR but TS and 2PL incomparable).
Schedule classification — 8 of 14 sessions, and it says 'use class inclusion'
Classification is the single most repeated task in the course: 8 of the 14 papers set it outright, a ninth (2024-08-30) asks the underlying theory, and it always requests the same list — VSR (with a view-equivalent serial schedule if it holds), CSR, 2PL, Strict 2PL, TS Mono, TS Multi. Nearly every paper adds “determine membership using class inclusion wherever possible”, and the published grader’s comments for January 2024 confirm a penalty was applied to answers that reached the right verdict without exploiting it.
So: one negative verdict on CSR immediately settles 2PL, Strict 2PL and TS Mono. One positive verdict on 2PL immediately settles CSR and VSR. Say so explicitly — that sentence is worth marks.
That paper’s schedule is the widget’s first example, so you can run the classification you just read and check every intermediate step against the marked solution — projections, arcs, the two view-equivalent serial schedules. Then edit the schedule and watch a single blind write flip the CSR verdict without touching VSR.
Conflict graph & schedule classification
Type a schedule the way the papers write it — r1(x) w2(y) r1(y) — and the widget runs the marked route: project onto each object, read the arcs off the projections, look for a cycle, then settle VSR. Watch which verdicts fall out of class inclusion for free.
Exercise A of the June 2026 paper — acyclic, and the marked solution lists exactly two view-equivalent serial schedules.
Serial: T3 T2 T1 · T2 T3 T1
Serial: T3 T2 T1 · T2 T3 T1
By inclusion · CSR holds, so VSR follows by inclusion — no enumeration needed. 2PL, Strict 2PL and TS still have to be checked: CSR does not imply them.
| x | r1 r3 w1 |
| y | r2 w2 r1 w1 |
| z | r3 w3 |
reads-from: r1(x) ← init · r3(x) ← init · r2(y) ← init · r1(y) ← w2(y) · r3(z) ← init
final writes: w1(x) · w1(y) · w3(z)
blind writes: none — so VSR and CSR coincide here
witness: r3(x) r3(z) w3(z) r2(y) w2(y) r1(x) w1(x) r1(y) w1(y)
A schedule's conflict graph contains a cycle. Which conclusions follow immediately, with no further work?
06 · Bridge
From theory to real schedulers
Everything above judges a schedule after the fact. A real scheduler must decide about operation k without knowing operation k+1.
Three things break when we move to a running system:
- CSR checking would be efficient if we knew the graph in advance — but we do not. Maintaining the conflict graph and re-testing acyclicity at every operation request is not feasible.
- The commit-projection assumption is unrealistic. Aborts do occur, and a scheduler cannot restrict its attention to transactions that will turn out to commit.
- The scheduler needs a simple, local decision criterion that avoids as many anomalies as possible with negligible overhead.
A vocabulary distinction follows. So far, denoted a schedule — an a-posteriori record of what happened, also called a history. For online control we also need arrival sequences: the order in which operation requests are emitted. The notation is the same and the meaning is clear from context, but the difference is real — the January 2025 exam turns on it, handing you an arrival sequence decorated with lock requests and asking what history a scheduler actually produces.
Two families of technique answer the problem, and the next two chapters take one each:
Pessimistic — locking
Assume collisions will happen and prevent them by controlling access to resources: if a resource is taken, make the requester wait, or pre-empt the holder. Chapter 6.
Optimistic — timestamps and versions
Assume collisions are rare; serve as many requests as possible and validate afterwards, possibly reading out-of-date versions. Chapter 7.
Commercial systems take the best of both — typically strict two-phase locking for writes combined with multiversion timestamps for reads.
Load-bearing ideas
- Five anomalies, by pattern: lost update
r1 r2 w2 w1; dirty readr1 w1 r2 abort1 w2; nonrepeatable readr1 r2 w2 r1; phantom update (same pattern, across a constraint); phantom insertr1 w2(new) r1. Phantom insert cannot be prevented by locking existing rows. - A schedule respects each transaction’s internal order. serial schedules against distinct ones — almost all are interleaved.
- VSR = same reads-from + same final writes as some serial schedule. Correct, permissive, and NP-complete to decide.
- CSR = same order for every conflicting pair. Decided by the conflict graph: acyclic ⟺ CSR, and any topological order gives a valid serial schedule.
- CSR ⊊ VSR, and the gap is exactly blind writes —
r1(x) w2(x) w1(x) w3(x)is the counter-example to memorise. No blind writes ⇒ the classes coincide. - Class inclusion is instructed and graded. Serial ⊂ 2PL ⊂ CSR ⊂ VSR. One CSR verdict settles three other classes; say so in the answer.
- Exam radar. Re-derive before the exam: the resource-projection method for building a conflict graph fast; the blind-write rescue that puts a non-CSR schedule into VSR; and the standard counter-example. Then read chapters 6 and 7, which supply the remaining classes on the list.