Enforcing Serializability by Locks Database Systems Ch. 18.3 Michael Symonds
First, Recall… The responsibility of the scheduler is to take requests from transactions and either: Allow them to operate on the database or Block the transaction until such time as it is safe to allow the transaction to execute.
? Locks - How Do They Work? A request is sent from a transaction The Scheduler now consults the lock table to guide it decision Generates a serializable schedule of actions ?
A locking scheduler enforces Conflict-Serializability, (which is a more stringent condition than correctness or even serializability.) But the use of locks must be proper in 2 senses: Consistency of Transactions Legality of Schedules
Consistency of Transactions Transactions can only read or write an element if has been granted a lock and has not yet released the lock. If a transaction locks an element, it must later unlock that element.
In other words… “Whenever transaction Ti has an action ri(X) or wi(X), then there is a previous action, li(X) with no intervening action ui(X), and there is a subsequent ui(X).”
Legality of schedules No two transactions may have locked the same element without one having first released the lock. In other words “If there is an action li(X) followed by lj(X) in a schedule, then somewhere between those actions there must be an action ui(X)”
How these concepts work together:
Locks(element, transaction) or (X,T) Locking Scheduler Grant requests if and only if the request results in a legal schedule Scheduler consults the lock table which tells, for each database element, whether a transactions holds a lock for that element The locking table, when there is only one kind of lock, is a table of relations: Locks(element, transaction) or (X,T)
Two-Phase Locking (2PL) In every transaction, ALL lock actions precede ALL unlock actions Two-Phase Locking is a condition, like consistency, on the order of actions in a transaction A transaction that obeys the 2PL condition is said to be a two-phase-locked transaction or 2PL transaction
Same transactions, one minor difference…
Conflict-Serializability The locking scheduler now enforces Conflict-Serializability
Why does Two-Phase Locking work? Each 2PL transaction may be thought to execute in its entirety at the instant it issues its first unlock request. So there is always at least one conflict-equivalent serial schedule for any schedule of 2PL transactions: the one in which the transactions appear in the same order as their first unlocks.
Proof: Converting any legal schedule S of consistent, two-phase locking transactions to a conflict-equivalent serial schedule: N = the number of transactions in our schedule, S Basis: n = 1, nothing to do, it’s already a serial schedule Otherwise, S involves transactions T1, T2, …, Tn. Ti is the transaction with the first unlock action in the entire schedule of S We’ll call that action Ui(X) Claim: it’s possible to move all read and write actions forward to the beginning of the schedule without passing any conflicting reads or writes.
Consider some action of Ti, say Wi(Y). Keep in mind: The issue of conflict-equivalence refers to the read and write actions only. As we swap read and/or write actions, lock and unlock actions are ignored. Once all the read and write actions have been ordered serially, the lock and unlock actions are placed around them as the various transactions require. Consider some action of Ti, say Wi(Y). Could it be preceded in S by some conflicting action, say Wj(Y)? If so, then in schedule S, the actions Uj(Y) and Li(Y) must intervene: …; Wj(Y); …; Uj(Y); …; Li(Y);…; Wi(Y); … But since we said Ti is the first to unlock, then Ui(X) must be shown to precede Uj(Y) in S, so S must look like: …; Wj(Y); …; Ui(X); …; Uj(Y); …; Li(Y); ..; Wi(Y); …
Ui(X) now appears before Li(Y), which violates the condition of Two-Phase Locking, therefore Ti is NOT a 2PL Transaction – a contradiction! Therefore this argument of the non-existence of pairs of conflicting actions allows us to conclude that it is indeed possible to move all actions of Ti forward to the beginning of S, using non-conflicting swaps, followed by the restoration of the lock and unlock actions of Ti. Furthermore, this proof extends to every subsequent Transaction in S, allowing us to convert all of S to be shown as conflict-serializable.
A Risk of Deadlock