Reputation: 199
I'm using JBoss EAP 6.0.1.GA (AS 7.1.3.Final) and the bundled Infinispan 'Brahma' 5.1.8.Final. I've configured Infinispan to be use a replicated, synchronous cache with isolation level = SERIALIZABLE and enabled batching on the cache.
Sample code I'm running:
Cache<String, List> cache = cacheContainer.getCache();
cache.startBatch();
List data = cache.get(key);
data.add(some value);
cache.put(key, data);
cache.endBatch(true);
edit Try as I might, if 2 nodes call this same block at the same time, every so often the data list only contains data from one node. It looks like it's a "* read" problem of various isolation levels, which I thought I guaranteed wouldn't happen by setting the isolation level to Serializable. /edit
I've also tried using an AdvancedCache, where my code would first do this to try to get the transaction lock as early as possible:
// javadocs on this flag seem to indicate this is a good idea if doing a get-update-put
Cache<String, List> cache = cacheContainer.getCache();
AdvancedCache<String, List> advancedCache =
cache.getAdvancedCache().withFlags(Flag.FORCE_WRITE_LOCK);
I've also played around with setting the transaction mode (NON_XA / Pessimistic), but I don't think that matters if I'm not actually using big-T Transactions (because of using batching instead)? And changing transaction modes I still see the above scenario occasionally).
Is there some code or configuration I'm missing or that is incorrect here?
Upvotes: 1
Views: 290
Reputation: 199
The answer was that version 5.x of Infinispan apparently had a bug where it wasn't acquiring a remote lock when
cache.getAdvancedCache().withFlags(Flag.FORCE_WRITE_LOCK)
was called. See https://issues.jboss.org/browse/ISPN-3266
I upgraded to 6.0.2Final and it seems to work now with no phantom/dirty reads.
(thanks to Wiliam at the JBoss community forums for his answer and help! https://community.jboss.org/message/884303)
Upvotes: 0
Reputation: 7204
Infinispan doesn't actually support the SERIALIZABLE isolation level, instead it downgrades to REPEATABLE_READ.
But I think the problem with your test is that Infinispan doesn't do defensive copies of the objects it stores - the assumption is that you will do the copy yourself and store the copy in the cache. So when you call data.add(some value)
, you modify the actual cache value and not a local copy.
You can change that behaviour by enabling storeAsBinary.storeValuesAsBinary
in the cache configuration.
Upvotes: 1