If 2 or more transaction are made 2 execute concurrently then they should result in a consistent state after the execution of all the transactions same as prior to their execution i.e they should be serializable schedule. A number of concurrency control techniques are applied in a concurrent database and one type of technique is locking the data item to prevent multiple transaction from accessing the items concurrently. Another set of protocol use timestamp. Locking technique: A lock is a variable associated with each data item that describes the status of the item with respect to possible operations that can be applied to it. Types of lock: depending upon types of lock the data manager gives or denies access to other operations on the same data item Binary Locks: will have 2 values locked and unlocked represented as 0 and 1. A transaction sends a request to a datamanager to access to a dataitem by first locking the data item using LOCK() operation .At this moment if any other operation
transcation tries to access same data item then it is forced to wait untill the transaction (previous one) that has locked the dataitem unlock the data item using unlocked command. Few rules must be followed when binary locking technique is used. LOCK() : operation must be issued by transaction before any update operation like read() or write() operation are performed on transaction. LOCK() :can’t be issued by transaction if already holds LOCK() on data item UNLOCK() : must be issued after all read() and write() operations are completed in a transaction. UNLOCK(): can’t be issued by transaction unless it already hold the lock on the data item.
Example for binary lock T1:LOCK(A) This example is T1:READ(A) A=100 seriazible T1:A:=A+200 A=300 schedule.Therefore, in T1:WRITE(A) case of a binary locking T1:UNLOCK(A) mechanism atmost one T2:LOCK(A) transaction can hold the T2:READ(A) A=300 lock on a particular T2:A:=A+300 A=600 dataitem .Thus no T2:WRITE(A) A=600 transaction can access T2:UNLOCK(A) the same item concurrently.
Lock-Based Protocols A lock is a mechanism to control concurrent access to a data item Data items can be locked in two modes : 1. exclusive (X) mode. Data item can be both read as well as written. X-lock is requested using lock-X instruction. In simplest manner if a transaction Ti has obtained an exclusive mode lock on data item X then Ti can both read and write data item Q. In other words if a transaction locks a data item and no other transaction can access that item or even read untill the lock is released by the transaction then such type of locking mechanism
2. shared (S) mode. Data item can only be read. S-lock is requested using lock-S instruction. Lock requests are made to concurrency-control manager. Transaction can proceed only after request is granted. In other way if a transaction Ti has obtained a shared mode lock on item X then Ti can read but can’t write data item X Few rules must be followed when read/write locking technique is used. LOCK() : operation must be issued by transaction before any update operation like read() or write() operation are performed on transaction. LOCK() :can’t be issued by transaction if already holds LOCK() on data item UNLOCK() : must be issued after all read() and write() operations are completed in a transaction.
Lock-Based Protocols Lock-compatibility matrix A transaction may be granted a lock on an item if the requested lock is compatible with locks already held on the item by other transactions Any number of transactions can hold shared locks on an item, but if any transaction holds an exclusive on the item no other transaction may hold any lock on the item. If a lock cannot be granted, the requesting transaction is made to wait till all incompatible locks held by other transactions have been released. The lock is then granted.
Example of a transaction performing locking: T2 T1 LOCKX(SUM) LOCKX(A) SUM:=0 READ(A) A=1000 LOCKS(A) A:=A-200 A=800 READ(A) A=800 WRITE(A) A=800 SUM:=SUM+A SUM=800 UNLOCK(A) UNLOCK(A) LOCKX(B) LOCKS(B) READ(B) B=900 READ(B) B=1100 B:=B+200 B=1100 SUM:=SUM+B SUM=1900 WRITE(B) B=1100 WRITE(SUM) SUM=1900 UNLOCK(B) UNLOCK(B) UNLOCK(SUM) IF EXECUTED SERIALLY THE OUTPUT WILL BE 1900
BUT IF RUNNING CONCURREENTLY THEN SUM WILL BE 2100 i.e LOSSUPDATE T2:LOCKX(SUM) T1:WRITE(B) B=1100 T2:SUM:=0 T1:UNLOCK(B) T2:LOCKS(A) A=1000 T2:LOCKS(B) T2:READ(A) T2:READ(B) B=1100 T2:SUM:=SUM+A SUM=1000 T2:SUM:=SUM +B T2:UNLOCK(A) SUM=1100 T1:LOCKX(A) T2:WRITE(SUM) SUM=1100 T1:READ(A) A=1000 T2:UNLOCK(B) T1:A:=A-200 A=800 T2:UNLOCK(SUM) T1:WRITE(A) A=800 AFTER TRANSACTION T1:UNLOCK(A) SUM+B IS 2100 .This is T1:LOCKX(B) inconsistent. This locking technique didn’t solve this T1:READ(B) B=900 problem because value of a/c T1:B:=B+200 B=1100 A was added to sum before modification was
Consider another example T1 UNLOCK(A) LOCKX(B) LOCKS(B) READ(B) B=200 READ(B) B=150 B:=B-50 B=150 UNLOCK(B) WRITE(B) B=150 DISPLAY(A+B) A+B=300 UNLOCK(B) THIS IS CLEAR THAT IF LOCKX(A) THEY RUN SEQUENTIALLY THE OUT PUT WILL BE 300 READ(A) A=100 A:=A+50 A=150 WRITE(A) A=150 UNLOCK(A) T2: LOCKS(A) READ(A) A=150
WHEN TRANSACTION ARE RUNNING CONCURRENTLY T1 T1 LOCKX(B) LOCKX(A) READ(B) B=200 READ(A) A=100 B:=B-50 B=150 A:=A+50 A=150 WRITE(B) B=150 WRITE(A) A=150 UNLOCK(B) UNLOCK(A) T2 THIS IS AN INCONSISTENT LOCKS(A) STATE OUTPUT WILL BE READ(A) A=100 250 UNLOCK(A) LOCKS(B) READ(B) B=150 UNLOCK(B) DISPLAY(A+B) A+B=250
NOW IF WE DELAY UNLOCKING TO THE END OF TRANSACTION THEN T1 READ(A) A=150 LOCKX(B) LOCKS(B) READ(B) B=200 READ(B) B=150 B:=B-50 B=150 UNLOCK(A) WRITE(B) B=150 UNLOCK(B) LOCKX(A) DISPLAY(A+B) READ(A) A=100 HERE ALSO A+B WILL BE A:=A+50 A=150 300 WRITE(A) A=150 UNLOCK(B) UNLOCK(A) T2 LOCKS(A)
Pitfalls of Lock-Based Protocols Consider the partial schedule Neither T3 nor T4 can make progress — executing lock-S(B) causes T4 to wait for T3 to release its lock on B, while executing lock-X(A) causes T3 to wait for T4 to release its lock on A. Such a situation is called a deadlock. To handle a deadlock one of T3 or T4 must be rolled back and its locks released.
DEAD LOCK: In other words a dead lock occurs when each transaction in a set of 2 or more transaction is waiting for some data item which is locked by other transaction in a set i.e two transaction are waiting for a condition that will never occur. The main reason for deadlock is exclusive locks acquired on data item by a transaction The potential for deadlock exists in most locking protocols. Deadlocks are a necessary evil.
(Cont.) Starvation is also possible if concurrency control manager is badly designed. For example: A transaction may be waiting for an X-lock on an item, while a sequence of other transactions request and are granted an S-lock on the same item. The same transaction is repeatedly rolled back due to deadlocks. For an example T2 has a shared mode lock on data item A and T1 request an exclusive lock on data item A,T1 can’t be given that lock untill T2 releases shared lock on data item A .But if T3 request a shared lock on A it will be given .At this moment if T2 releases its lock on A,still T1 will have to wait for T3 to finish.In a similar way there may exist a sequence of transactions requesting shared lock on data item A and each releases its lock a short while after it is granted ,But T1 will never get the exclusive lock on data item A.Thus T1 will never progress and such situation is starvation Concurrency control manager can be designed to prevent starvation.
This is a protocol which ensures conflict- serializable schedules. Avoiding starvation: It can be avoided by granting the locks in following manner.When a transaction Ti request a lock on data item A in a particular mode M the database manager grants the lock provided that 1.There is no other transaction holding a lock on data item A in a mode that conflicts with M. 2.There is no other transaction that is waiting for a lock on A and that made its lock request before Ti Two phase locking Phase 1: Growing Phase transaction may obtain locks transaction may not release locks Phase 2: Shrinking Phase transaction may release locks transaction may not obtain locks
The Two-Phase Locking:The protocol assures serializability. It can be provedthat the transactions can be serialized in the order of their lock points (i.e. thepoint where a transaction acquired its final lock). T1 T1 READ(B) READ(B) B:=B-50 B:=B-50 WRITE(B) WRITE(B) LOCKX(A) UNLOCK(B) READ(A) LOCKX(A) A:=A+50 READ(A) WRITE(A) A:=A+50 UNLOCK(B) WRITE(A) UNLOCK(A) UNLOCK(A) Above example is 2 phase Above example is not 2 phase because unlocks appears after because unlock(b) appears all lock operation before lock(a)
Two-phase locking does not ensure freedom from deadlocks Cascading roll-back is possible under two-phase locking. To avoid this, follow a modified protocol called strict two-phase locking. Here a transaction must hold all its exclusive locks till it commits/aborts. This requirement ensures that any data written by uncommitted transaction are locked in exclusive mode untill the transaction commits,preventing any other transaction from reading the data. Rigorous two-phase locking is even stricter: here all locks are held till commit/abort. In this protocol transactions can be serialized in the order
Conversion of locks:TRANSACTION ARE RUNNING CONCURRENTLY T1 If we are following 2 phase locking READ(A) protocol the transaction T1 must lock READ(B) data item in exclusive mode as it has …. to perform write operation on item A. …. The other transaction T2 just need to …. read the data item A but is unable to WRITE(A) get shared lock on item A untill T1 T2 perform write operation on A1.Since READ(A) T1 needs an exclusive lock on A only READ(B) at the end of its execution where it DISPLAY(A+B) perform write operation on A it will be better if T1 could initially lock A1 in shared mode and later on chages lock to exclusive mode at that time when it has to perform write operation.if we do so then both transaction can share a
A mechanism is provided for upgrading a shared lock to exclusive lock and downgrading an exclusive lock to a shared lock. Conversion from shared to exclusive modes is denoted by upgrade Conversion from exclusive to shared mode by downgrade. Lock conversion is not allowed to occur arbitrarily.Upgrading takes place only in growing phase whereas downgrading takes place in only shrininking phase T1 LOCKS(A) LOCKS(B) READ(A) READ(B) UPGRADE(A)
Thus the final scheme for automatic generation of an appropiate lock andunlock instruction for a transaction is as follows When a trnsaction Ti issues a READ(A) operation it issue a locks(A) instruction followed by READ(A) instruction When a transaction Ti issues a write(A) operation the system check to see whether Ti has already hold a shared lock on data item A. If yes the system will issue an upgrade(A) instruction followed by write(A). Otherwise the system will issue a LOCKX(A) instruction followed by write(a) instruction All locks obtained by transaction are unlocked after the transaction commit or abort
Implementation of Locking A Lock manager can be implemented as a separate process to which transactions send lock and unlock requests The lock manager replies to a lock request by sending a lock grant messages (or a message asking the transaction to roll back, in case of a deadlock) The requesting transaction waits until its request is answered The lock manager maintains a datastructure called a lock table to record granted locks and pending requests
Lock Table Black rectangles indicate granted locks, white ones indicate waiting requests Lock table also records the type of lock granted or requested New request is added to the end of the queue of requests for the data item, and granted if it is compatible with all earlier locks Unlock requests result in the request being deleted, and later requests are checked to see if they can now be granted If transaction aborts, all waiting or granted requests of the transaction are deleted lock manager may keep a list of locks held by each transaction, to implement this efficiently
Insert and Delete Operations If two-phase locking is used : A delete operation may be performed only if the transaction deleting the tuple has an exclusive lock on the tuple to be deleted. A transaction that inserts a new tuple into the database is given an X- mode lock on the tuple Insertions and deletions can lead to the phantom phenomenon. A transaction that scans a relation (e.g., find all accounts in Perryridge) and a transaction that inserts a tuple in the relation (e.g., insert a new account at Perryridge) may conflict in spite of not accessing any tuple in common. If only tuple locks are used, non-serializable schedules can result: the scan transaction may not see the new account, yet may be serialized before the insert transaction.
Insert and Delete Operations The transaction scanning the relation is reading information that indicates what tuples the relation contains, while a transaction inserting a tuple updates the same information. The information should be locked. One solution: Associate a data item with the relation, to represent the information about what tuples the relation contains. Transactions scanning the relation acquire a shared lock in the data item, Transactions inserting or deleting a tuple acquire an exclusive lock on the data item. (Note: locks on the data item do not conflict with locks on individual tuples.) Above protocol provides very low concurrency for insertions/deletions. Index locking protocols provide higher concurrency while preventing the phantom phenomenon, by requiring locks on certain index buckets.