For resource (database and cache) needs to be managed for concurrent access to avoid damaging data integrity, it is often time achieved by locking mechanism (read and write lock). For a transaction to be isolated from other transactions, this mechanism is very important. There are 5 different isolation levels that can be achieved via read and write lock. We know that the higher the isolation level, the lower the degree of concurrency. Therefore, our goal here is to get the transaction isolated while minimizing the impact of concurrency. This article, I will go through how to use read/ write lock to achieve various isolation levels and how to improve concurrency while achieve highest degree of transaction isolation.
5 isolation levels
- NONE - There is no locking at this level. Your code needs to take care of it.
- READ-UNCOMMITTED - Exclusive lock for writes while reads don’t need to acquire a lock. It means when Tx1 get a write lock and change the data without committed, Tx2 can read the uncommitted data (dirty read).
- READ-COMMITTED - Use a read-write lock; reads succeed acquiring the lock when there are only reads, writes have to wait until there are no more readers holding the lock, and readers are blocked acquiring the lock until there are no more writers holding the lock. However, reads typically release the read-lock when done, so that a subsequent read to the same data of the same transaction has to re-acquire a read-lock; this leads to nonrepeatable reads, where 2 reads of the same data might return different values because write can happen in between 2 reads.
- REPEATED-READ - Data can be read while there is no write and vice versa. Write lock is not given until the Tx holding the read lock is committed. This level prevents “non-repeatable read” but it does not completely prevent the so-called “phantom read” where new data can be inserted into the tree from another transaction.
- SERIALIZABLE - Data access is synchronized with exclusive locks. Only 1 writer or reader can have the lock at any given time. Locks are released at the end of the transaction. Regarded as very poor for performance and thread/transaction concurrency.
Optimistic LockingÂ
The lock mechanism above is using pessimistic locking. To achieve better concurrency, you may want to use optimistic locking. When optimistic locking is turned on, isolation level is ignored because you are using different mechanism for data integrity protection. For optimistic locking, the data is versioned and all calls in the transaction work on the copy of the data rather than the actual data. When the transaction commits, its workspace is merged back and version is checked. If there is a version mismatch, the transaction throws a RollbackException when committing and the commit fails. Optimistic locking uses the same locks we speak of above, but the locks are only held for a very short duration - at the start of a transaction to build a workspace, and when the transaction commits and has to merge data back into the tree. So while optimistic locking may occasionally fail if version validations fail or may run slightly slower than pessimistic locking due to the inevitable overhead and extra processing of maintaining workspaces, versioned data and validating on commit, it does buy you a near-SERIALIZABLE degree of data integrity while maintaining a very high level of concurrency.






































(4.75 out of 5)
No Comment Received
Sorry the comment area are closed for non registered users