use of org.infinispan.hibernate.cache.commons.util.VersionedEntry in project infinispan by infinispan.
the class VersionedTest method testCollectionUpdate.
@Test
public void testCollectionUpdate() throws Exception {
// the first insert puts VersionedEntry(null, null, timestamp), so we have to wait a while to cache the entry
TIME_SERVICE.advance(1);
withTxSession(s -> {
Item item = s.load(Item.class, itemId);
OtherItem otherItem = new OtherItem();
otherItem.setName("Other 1");
s.persist(otherItem);
item.addOtherItem(otherItem);
});
withTxSession(s -> {
Item item = s.load(Item.class, itemId);
Set<OtherItem> otherItems = item.getOtherItems();
assertFalse(otherItems.isEmpty());
otherItems.remove(otherItems.iterator().next());
});
AdvancedCache collectionCache = TEST_SESSION_ACCESS.getRegion(sessionFactory(), Item.class.getName() + ".otherItems").getCache();
CountDownLatch putFromLoadLatch = new CountDownLatch(1);
AtomicBoolean committing = new AtomicBoolean(false);
CollectionUpdateTestInterceptor collectionUpdateTestInterceptor = new CollectionUpdateTestInterceptor(putFromLoadLatch);
AnotherCollectionUpdateTestInterceptor anotherInterceptor = new AnotherCollectionUpdateTestInterceptor(putFromLoadLatch, committing);
AsyncInterceptorChain interceptorChain = collectionCache.getAsyncInterceptorChain();
interceptorChain.addInterceptorBefore(collectionUpdateTestInterceptor, CallInterceptor.class);
interceptorChain.addInterceptor(anotherInterceptor, 0);
TIME_SERVICE.advance(1);
Future<Boolean> addFuture = executor.submit(() -> withTxSessionApply(s -> {
awaitOrThrow(collectionUpdateTestInterceptor.updateLatch);
Item item = s.load(Item.class, itemId);
OtherItem otherItem = new OtherItem();
otherItem.setName("Other 2");
s.persist(otherItem);
item.addOtherItem(otherItem);
committing.set(true);
return true;
}));
Future<Boolean> readFuture = executor.submit(() -> withTxSessionApply(s -> {
Item item = s.load(Item.class, itemId);
assertTrue(item.getOtherItems().isEmpty());
return true;
}));
addFuture.get();
readFuture.get();
interceptorChain.removeInterceptor(CollectionUpdateTestInterceptor.class);
interceptorChain.removeInterceptor(AnotherCollectionUpdateTestInterceptor.class);
withTxSession(s -> assertFalse(s.load(Item.class, itemId).getOtherItems().isEmpty()));
}
use of org.infinispan.hibernate.cache.commons.util.VersionedEntry in project infinispan by infinispan.
the class NonStrictAccessDelegate method putFromLoad.
@Override
public boolean putFromLoad(Object session, Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) throws CacheException {
long lastRegionInvalidation = region.getLastRegionInvalidation();
if (txTimestamp < lastRegionInvalidation) {
log.tracef("putFromLoad not executed since tx started at %d, before last region invalidation finished = %d", txTimestamp, lastRegionInvalidation);
return false;
}
assert version != null;
if (minimalPutOverride) {
Object prev = cache.get(key);
if (prev != null) {
Object oldVersion = getVersion(prev);
if (oldVersion != null) {
if (versionComparator.compare(version, oldVersion) <= 0) {
if (log.isTraceEnabled()) {
log.tracef("putFromLoad not executed since version(%s) <= oldVersion(%s)", version, oldVersion);
}
return false;
}
} else if (prev instanceof VersionedEntry && txTimestamp <= ((VersionedEntry) prev).getTimestamp()) {
if (log.isTraceEnabled()) {
log.tracef("putFromLoad not executed since tx started at %d and entry was invalidated at %d", txTimestamp, ((VersionedEntry) prev).getTimestamp());
}
return false;
}
}
}
// we can't use putForExternalRead since the PFER flag means that entry is not wrapped into context
// when it is present in the container. TombstoneCallInterceptor will deal with this.
// Even if value is instanceof CacheEntry, we have to wrap it in VersionedEntry and add transaction timestamp.
// Otherwise, old eviction record wouldn't be overwritten.
CompletableFuture<Void> future = putFromLoadMap.eval(key, new VersionedEntry(value, version, txTimestamp));
// Rethrow exceptions
future.join();
return true;
}
use of org.infinispan.hibernate.cache.commons.util.VersionedEntry in project infinispan by infinispan.
the class DomainDataRegionImpl method runInvalidation.
@Override
protected void runInvalidation() {
if (strategy == null) {
throw new IllegalStateException("Strategy was not set");
}
switch(strategy) {
case NONE:
case VALIDATION:
super.runInvalidation();
return;
case TOMBSTONES:
removeEntries(entry -> localCache.remove(entry.getKey(), entry.getValue()));
return;
case VERSIONED_ENTRIES:
// no need to use this as a function - simply override all
VersionedEntry evict = new VersionedEntry(factory.nextTimestamp());
removeEntries(entry -> localCache.put(entry.getKey(), evict, tombstoneExpiration, TimeUnit.MILLISECONDS));
return;
}
}
Aggregations