I am using Inifinispan as a local, non-distributed cache in a stateless session bean inside of AS 6.0.0 to cache versioned records from the database. The cache is configured to take part in the container managed transaction. The data is being put in the cache at both db read and db write time. To avoid any race conditions that can leave the cache out of sync with the db, I am making use of get(), replace() and putIfAbsent() API to get the old version of any key being updated, perform a version check and ensure the data being put into cache is replacing the expected old value from the time of the version check.
Having said all this, in the transactional mode, the get/replace and putIfAbsent are locking rows while the transaction is open which essentially means I'm doing pessimistic locking and since not all keys are present I can easily get deadlocks.
My questions is, is there an interface I can use to do the version validation at prepare time in order to avoid the deadlocks, or a better way to perform the version checks of the records I'm putting in the cache?
I know there is some discussion about optimistic locks in version 5.1, however I'm still not sure this is exactly what I need as they are mainly concentrating on the distributed node locking. I am currently using Infinispan 'Ursus' 4.2.0.FINAL as part of JBoss AS 6.0.0 Final.
I have tried to read as much as I can in the docs and forum but I'm sure this answer is just hiding from me, so I apologize if I missed an existing post on this.
This is my cache configuration (tx lookup class is dummy so I can run my test case outside of the AS server):
<?xml version="1.0" encoding="UTF-8"?> <infinispan xmlns="urn:infinispan:config:4.2"> <global> <transport clusterName="Test" /> <globalJmxStatistics enabled="true" /> </global> <namedCache name="test"> <locking isolationLevel="READ_COMMITTED" concurrencyLevel="1000" lockAcquisitionTimeout="15000" useLockStriping="false" /> <eviction wakeUpInterval="5000" maxEntries="10000" strategy="LRU" /> <expiration maxIdle="100000" /> <transaction transactionManagerLookupClass="org.infinispan.transaction.lookup.DummyTransactionManagerLookup" syncRollbackPhase="false" syncCommitPhase="false" useEagerLocking="false" /> </namedCache> </infinispan>