Section 9 · 8 min read
Transactions and concurrency control
ACID properties, schedules, conflict and view serializability with precedence graphs, recoverable, cascadeless and strict schedules, two-phase locking variants, and timestamp ordering.
On this page
Transactions and ACID
A transaction is a sequence of reads and writes that the DBMS treats as one logical unit, ending in commit or abort.
| Property | Meaning | Ensured by |
|---|---|---|
| Atomicity | All of it happens or none of it does | Recovery manager (undo using the log) |
| Consistency | A correct transaction takes a consistent state to a consistent state | Programmer and integrity constraints |
| Isolation | Concurrent execution looks like some serial execution | Concurrency control |
| Durability | Committed changes survive crashes | Recovery manager (redo, write-ahead log) |
Transaction states
Active, then partially committed (last statement executed), then committed; or failed, then aborted (rolled back). After an abort the transaction can be restarted or killed.
Schedules
Notation: and are a read and write of item X by transaction ; and are commit and abort.
A schedule interleaves the operations of several transactions while keeping each transaction's own order. A serial schedule runs transactions one after another; with n transactions there are serial schedules. Two transactions with and operations have schedules.
Anomalies that concurrency control prevents
- Lost update: ; 's write is overwritten.
- Dirty read: reads a value written by , which later aborts.
- Unrepeatable read: reads X twice and changes it in between.
- Phantom: a repeated range query sees new rows inserted by another transaction.
Conflict serializability
Two operations conflict if they belong to different transactions, access the same item, and at least one is a write. So the conflicting pairs are read-write, write-read and write-write. Two reads never conflict.
Two schedules are conflict equivalent if one can be turned into the other by swapping adjacent non-conflicting operations; equivalently, every conflicting pair appears in the same order. A schedule is conflict serializable if it is conflict equivalent to some serial schedule.
Precedence graph test
- One node per transaction.
- For each conflicting pair where 's operation comes first, draw .
- The schedule is conflict serializable if and only if the graph has no cycle.
- Each topological order of the graph is an equivalent serial schedule.
View serializability
Two schedules are view equivalent if, for every data item:
- The same transaction reads the initial value.
- Every read reads the value written by the same transaction (reads-from).
- The same transaction performs the final write.
A schedule is view serializable if it is view equivalent to some serial schedule.
- Every conflict serializable schedule is view serializable.
- A view serializable schedule that is not conflict serializable must contain a blind write (a write of X without a preceding read of X by that transaction).
- Testing view serializability is NP-complete in general, so in practice you check candidate serial orders.
Recoverability
These properties concern commits and aborts, independently of serializability.
| Property | Rule |
|---|---|
| Recoverable | If reads from , then commits before commits |
| Cascadeless (ACA) | Transactions read only committed values: if reads X written by , comes before that read |
| Strict | No transaction reads or writes X until the last transaction that wrote X has committed or aborted |
Strict cascadeless recoverable. A schedule that is not recoverable can leave the database unable to undo an abort, because the reader has already committed. A recoverable but not cascadeless schedule may need cascading rollback.
Lock-based protocols
Shared lock (S) for reading, exclusive lock (X) for writing. S is compatible with S; X is compatible with nothing.
Two-phase locking (2PL)
Each transaction has a growing phase (acquire locks, release none) followed by a shrinking phase (release locks, acquire none). The point where it holds all its locks is the lock point.
| Variant | Rule | Guarantees | Deadlock-free? |
|---|---|---|---|
| Basic 2PL | Two phases | Conflict serializable (order of lock points) | No |
| Strict 2PL | Hold X locks until commit/abort | Conflict serializable and strict | No |
| Rigorous 2PL | Hold all locks until commit/abort | Serializable in commit order, strict | No |
| Conservative 2PL | Acquire every lock before starting | Conflict serializable | Yes |
Basic 2PL can produce cascading aborts. Not every conflict serializable schedule can be produced by 2PL.
Deadlock handling with timestamps
- Wait-die (non-preemptive): an older transaction may wait for a younger one; a younger one requesting from an older one dies (aborts) and restarts with the same timestamp.
- Wound-wait (preemptive): an older transaction wounds (aborts) the younger holder; a younger one waits for an older one.
Both prevent deadlock and starvation because the restarted transaction keeps its original timestamp and eventually becomes the oldest.
Timestamp ordering
Each transaction gets a timestamp at start. Each item X keeps and , the largest timestamps that read and wrote it.
- issues : if , reject and roll back T. Otherwise allow and set .
- issues : if or , reject and roll back T. Otherwise allow and set .
Thomas write rule: if but , ignore the obsolete write instead of rolling back. This allows some view serializable schedules that are not conflict serializable.
Basic timestamp ordering guarantees conflict serializability and is deadlock-free (no transaction waits), but it can cause starvation and is not recoverable unless commits are also controlled.
Worked examples
Worked example 1: a cycle in the precedence graph
Conflicting pairs:
- before : .
- before , and before : , .
- before : .
- before : .
is a cycle, so S is not conflict serializable. It is not view serializable either. reads the initial A, so in any view-equivalent serial order must come before (which writes A). reads the initial B, so must come before (which writes B). Both cannot hold.
Changing the schedule to leaves edges , , and no cycle. The only equivalent serial order is .
Worked example 2: counting serializable schedules
and . There are schedules. Every pair across the two transactions except conflicts. If 's read and 's read both happen before either write, the writes create edges in both directions. Checking all six, only the two serial schedules have an acyclic graph. Answer: 2.
When counting, list the conflicting pairs and count the interleavings in which they all point the same way; it is often easier to count the bad cases and subtract.
Worked example 3: view serializable but not conflict serializable
- before : . before : . Cycle, so not conflict serializable.
- View check against : in S, reads the initial Y and writes last. In the serial order, runs first and reads the initial Y, and runs last. Same reads-from, same final writer. View serializable.
The blind writes and make this possible.
Worked example 4: recoverability
reads A written by , but commits first. If now aborts, has committed a value derived from data that never existed. S is not recoverable. Swapping the commits ( before ) makes it recoverable, but still not cascadeless, because reads an uncommitted value.
Worked example 5: timestamp ordering trace
, , all item timestamps start at 0. Operations:
- : . Allowed, .
- : . A younger transaction has already read X, so 's write would arrive too late in timestamp order. is rolled back.
Under the Thomas write rule the outcome is the same here, because the rule only ignores writes that are older than , not writes that are older than .
Common traps
- Drawing an edge for two reads. Only pairs with at least one write conflict.
- Drawing edges between operations of the same transaction.
- Treating "not conflict serializable" as "not serializable". Check view serializability when there are blind writes.
- Confusing recoverable with cascadeless. Recoverable is about commit order; cascadeless is about reading only committed data.
- Saying 2PL prevents deadlock. Only conservative 2PL does.
- Applying the read rule to a write in timestamp ordering. A write checks both RTS and WTS; a read checks only WTS.
- Thinking Thomas write rule saves a write that is older than RTS. It only skips writes older than WTS.
- In wait-die, the older transaction waits and the younger dies. In wound-wait, the older wounds and the younger waits.
Quick revision
- Atomicity and durability: recovery. Isolation: concurrency control. Consistency: application plus constraints.
- Conflict = different transactions, same item, at least one write.
- Precedence graph acyclic iff conflict serializable; topological orders give serial equivalents.
- Conflict serializable implies view serializable; the converse needs no blind writes.
- Strict cascadeless recoverable.
- 2PL gives conflict serializability; strict 2PL adds strictness; conservative 2PL avoids deadlock.
- TO read: reject if . TO write: reject if or . Thomas: ignore a write with (when ).
- Wait-die: old waits, young dies. Wound-wait: old wounds, young waits.
- n transactions: serial schedules; m and n operations: interleavings.