Lock-Based Scheduler

This is a Scheduler that gives Conflict-Serializable Schedule

This scheduler is pessimistic:

  • it assumes that something will go wrong, and it's going to prevent that

Notation:

  • w(X) - write X
  • r(X) - read X
  • l(X) - lock X
  • u(X) - unlock X

Rule:

  • before a transaction Ti can read or write a database item X, it must obtain the lock on X
  • if Ti requests a lock that is already taken by other transaction Tj, it's paused until Tj releases the lock
  • so it's impossible for both Ti and Tj to have a lock on the same database element at the same time


Example

The following is a legal lock-based schedule:

T1 T2
l1(A),r1(A)
w1(A)
l1(B),u1(A)
l1(A),r2(A)
w2(A)
l2(B) lock is denied, T2 pauses
r1(B),w1(B)
r1(B),w1(B)
u1(B) T1 releases B, T2 can proceed
l2(B),u2(A)
r2(B),w2(B)
u2(B)


Another example:

S=

T1 T2
l1(A),r1(A),w1(A),u1(A),
l2(A),r2(A),w2(A),u2(A),
l2(B),r2(B),w2(B),u2(B),
l1(B),r1(B),w1(B),u1(B)

Is it conflict-serializable?

  • We build a precedence graph:
    • pred-graph-3.png
  • there is a cycle! no conflict serializability
  • so even if a lock-based schedule is legal, it doesn't mean it's conflict-serializable


Tho-Phase Locking

To get a conflict-serializable schedule:

  • for each Ti, all lock requests li must precede unlock requests ui

In other words

  • we can acquire as many locks as you want,
  • but then can only unlock them without being able to acquire them again
  • cannot do li(X),ui(X),li(X),ui(X) within the same transaction Ti

all locks are released after the entire manipulation with a DB object is completed

  • this way the schedule is guaranteed to be conflict-serializable


Theorem

A schedule S obtained by Tho-Phase Locking is conflict-serializable


Proof:

Suppose we have a schedule S in which a transaction doesn't lock after unlocking

  • we want to show that we can transform S into a conflict-serializable one by conflict-free swapping

For a schedule with one transaction it's trivial

  • assume several transactions

Suppose we have the following schedule:

  • S=...,wB(X),...,uB(X),...,lA(X),...,uA(X),...,rA(X),...
  • since B unlocks X there must be lB(X) that precedes uB(X)
  • in this case all actions for element X are performed only by transaction B
  • by conflict-free swapping can move all actions on X to the front of the schedule
  • then remove them and repeat for the remaining elements


In Practice

  • Transaction manager sends read/write requests
  • The scheduler itself inserts locks and unlocks - the transactions don't know anything about them
  • Also the locks are usually released after commit
  • so if a transaction T2 waits for a lock, it will usually wait until another transaction T1 that keeps the lock commits


Cons and Pros

  • Locking is very effective when we have many transactions that both read and write
  • When you have few transactions that write it's not efficient - many transactions will have to wait for locks


Other Approaches

There are no problems with two transactions that read at the same time (as long as none of them write)

  • there are different kind of locks for that
  • Shared Locks - for reading at the same time
  • Exclusive Locks - if you also want to write

Also there are hierarchical locks

  • locks not on a tuple, but on the whole block


Sources