1

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?

2 Answers2

1

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.

Dan Berindei
  • 7,054
  • 3
  • 41
  • 48
  • Thanks for your reply! About the SERIALIZABLE configuration, you're right, I see in the Infinispan user guide that only READ_COMMITTED and REPEATABLE_READ are supported, yet the jboss-as-infinispan schema allows SERIALIZABLE. Weird. I'm looking at trying your suggestion for storeValuesAsBinary, but the user guide says it's available from v5.3 (javadoc says v5.2), and I'm currently testing on v5.1.8. I had looked at upgrading anyway to see if that might fix the issue, so I can try that at the same time :) I edited my original question somewhat to hopefully make my issue more clear. – Phillip Atkinson Aug 14 '14 at 02:47
  • The option exists in 5.1.8 as well, it was just moved in 5.2. but I would recommend upgrading to 5.2.x anyway... – Dan Berindei Aug 15 '14 at 11:03
  • I see! Thanks for the explanation. I've since upgraded to 6.0.2 and am using this configuration value. – Phillip Atkinson Aug 18 '14 at 03:56
0

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)