Optimistic Locking in JBossCache
Introduction
JBossCache currently locks data nodes (based on isolation level) in a pessimistic fashion, which essentially requires data nodes to be locked (either for reading or writing) for the entire duration of a transaction. While very reliable and easy to implement, this approach does have scalability issues.
This implementation of Optimistic locking aims to solve this problem of locked nodes by versioning the data.
Reasons for use
Typically the main reasons for using an optimistic locking scheme centre around performance and deadlock prevention.
Performance
With optimistic locking, greater concurrecy can be achieved since data is locked (either read or write) only for a part of the commit phase of a transaction, rather than the entire duration of the transaction as is the case with pessimistic locks.
This is done while still maintaining a high level of data integrity (close to SERIALIZABLE in DB isolation level parlance) by maintaining copies and versioning the data.
In addition to improving throughput and scalability, further improvements are seen as when using a replicated cache, replication would only occur when transactions complete successfully (see section below re: transactions, as all requests are treated as transactional)
Also, see JBossCacheOptimisticLockingPerformance
Deadlock prevention
Deadlocks may occur with pessimistic locks. Imagine the situation where User A performs a transaction, that involves reading data node X, and then writing to data node Y. User B performs a transaction where it reads data node Y and writes to data node X. If they run concurrently, and they both perform their first steps, data node X is read locked (by User A) and data node Y is read locked by (User B). Neither transaction can continue because they both require write locks on data nodes Y and X respectively, but neither tx can complete to release the read locks.
Because of the improved concurrency afforded by versioning the data, optimistic locking would prevent such deadlocks from occuring.
Design
This implementation of optimistic locking uses some simple concepts to allow for adt nodes not to be locked throughout the duration of a transaction.
Transactions
Even simple operations that are not performed within the context of a transaction are treated as transactional. An interceptor intercepts all calls to the cache at a very early stage and sets up a local transaction if necessary.
Workspaces
A workspace is created, in which a snapshot of data in the cache is maintained. This workspace, attached to the transaction, serves up reads and writes to the cache rather than allowing such calls to access the cache directly.
Versioning
Data nodes are versioned. Any time new data is written back to the cache, the node's version is updated.
Verification
Upon completion of a transaction (during a commit) modified nodes in the workspace are checked for integrity by comparing their versions against the versions of their counterparts in the underlying cache. If the versions tally up, the commit is allowed to proceed and changes are written back to the cache. If not, an exception is thrown and the transaction fails. Note that this is the only stage where locks are acquired on the cache
Configuration
The only change needed, to enable optimistic locking, is to use OPTIMISTIC as your node locking scheme:
<!-- Node locking scheme: OPTIMISTIC PESSIMISTIC (default) --> <attribute name="NodeLockingScheme">OPTIMISTIC</attribute>
Note that the IsolationLevel attribute is IGNORED if your NodeLockingScheme above is OPTIMISTIC.
Also, note that you have to set a transaction manager class to use optimistic locking.
Current status
Optimistic locking is in the CVS HEAD of JBossCache, and the code will be available in JBossCache 1.2.4 although not formally released and/or supported. During this time optimistic locking will undergo performance benchmarks and tuning, with a plan to be formally released in JBossCache 1.3.
Please note that beta releases of 1.2.4 had a serious bug in the optimistic locking code http://jira.jboss.com/jira/browse/JBCACHE-329 - this is fixed in the final release of 1.2.4 and in CVS HEAD (to become 1.3)
JIRA
... on this feature is over here: http://jira.jboss.com/jira/browse/JBCACHE-69
Implementation Details
... are available here - OptimisticNodeLockingImpl
Comments