我正在使用JBoss EAP 6.0.1.GA(AS 7.1.3.Final)和捆绑的Infinispan'Brahma'5.1.8.Final。我已将Infinispan配置为使用具有隔离级别= SERIALIZABLE的复制同步缓存,并在缓存上启用批处理。
我正在运行的示例代码:
Cache<String, List> cache = cacheContainer.getCache();
cache.startBatch();
List data = cache.get(key);
data.add(some value);
cache.put(key, data);
cache.endBatch(true);
修改的 尽量尝试,如果2个节点同时调用同一个块,那么数据列表通常只包含来自一个节点的数据。看起来它是各种隔离级别的“*读取”问题,我认为通过将隔离级别设置为Serializable,我保证不会发生这种情况。 /编辑
我也尝试过使用AdvancedCache,我的代码首先尝试尽可能早地获取事务锁:
// 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);
我也玩过设置事务模式(NON_XA / Pessimistic),但是如果我实际上没有使用big-T事务(因为使用批处理),我认为不重要?并且改变交易模式我偶尔会看到上述情况。
我是否缺少某些代码或配置,或者这里有错误?
答案 0 :(得分:1)
Infinispan实际上并不支持SERIALIZABLE隔离级别,而是降级为REPEATABLE_READ。
但我认为你的测试存在的问题是Infinispan并没有对它存储的对象进行防御性复制 - 假设你自己复制并将副本存储在缓存中。因此,当您调用data.add(some value)
时,您将修改实际缓存值而不是本地副本。
您可以通过在缓存配置中启用storeAsBinary.storeValuesAsBinary
来更改该行为。
答案 1 :(得分:0)
答案是,Infinispan的5.x版本显然有一个错误,当它
时没有获得远程锁定cache.getAdvancedCache().withFlags(Flag.FORCE_WRITE_LOCK)
被召唤。见https://issues.jboss.org/browse/ISPN-3266
我升级到6.0.2Final,现在似乎没有幻像/脏读。
(感谢Wiliam在JBoss社区论坛上的回答和帮助!https://community.jboss.org/message/884303)