use of org.hibernate.engine.spi.SharedSessionContractImplementor in project hibernate-orm by hibernate.
the class AbstractGeneralDataRegionTest method testEvictAll.
/**
* Test method for {@link QueryResultsRegion#evictAll()}.
* <p/>
* FIXME add testing of the "immediately without regard for transaction isolation" bit in the
* CollectionRegionAccessStrategy API.
*/
public void testEvictAll() throws Exception {
withSessionFactoriesAndRegions(2, (sessionFactories, regions) -> {
GeneralDataRegion localRegion = regions.get(0);
GeneralDataRegion remoteRegion = regions.get(1);
AdvancedCache localCache = ((BaseGeneralDataRegion) localRegion).getCache();
AdvancedCache remoteCache = ((BaseGeneralDataRegion) remoteRegion).getCache();
SharedSessionContractImplementor localSession = (SharedSessionContractImplementor) sessionFactories.get(0).openSession();
SharedSessionContractImplementor remoteSession = (SharedSessionContractImplementor) sessionFactories.get(1).openSession();
try {
Set localKeys = localCache.keySet();
assertEquals("No valid children in " + localKeys, 0, localKeys.size());
Set remoteKeys = remoteCache.keySet();
assertEquals("No valid children in " + remoteKeys, 0, remoteKeys.size());
assertNull("local is clean", localRegion.get(null, KEY));
assertNull("remote is clean", remoteRegion.get(null, KEY));
localRegion.put(localSession, KEY, VALUE1);
assertEquals(VALUE1, localRegion.get(null, KEY));
remoteRegion.put(remoteSession, KEY, VALUE1);
assertEquals(VALUE1, remoteRegion.get(null, KEY));
localRegion.evictAll();
// This should re-establish the region root node in the optimistic case
assertNull(localRegion.get(null, KEY));
localKeys = localCache.keySet();
assertEquals("No valid children in " + localKeys, 0, localKeys.size());
// Re-establishing the region root on the local node doesn't
// propagate it to other nodes. Do a get on the remote node to re-establish
// This only adds a node in the case of optimistic locking
assertEquals(null, remoteRegion.get(null, KEY));
remoteKeys = remoteCache.keySet();
assertEquals("No valid children in " + remoteKeys, 0, remoteKeys.size());
assertEquals("local is clean", null, localRegion.get(null, KEY));
assertEquals("remote is clean", null, remoteRegion.get(null, KEY));
} finally {
localSession.close();
remoteSession.close();
}
});
}
use of org.hibernate.engine.spi.SharedSessionContractImplementor in project hibernate-orm by hibernate.
the class AbstractRegionAccessStrategyTest method putFromLoadTest.
/**
* Simulate 2 nodes, both start, tx do a get, experience a cache miss, then
* 'read from db.' First does a putFromLoad, then an update (or removal if it is a collection).
* Second tries to do a putFromLoad with stale data (i.e. it took longer to read from the db).
* Both commit their tx. Then both start a new tx and get. First should see
* the updated data; second should either see the updated data
* (isInvalidation() == false) or null (isInvalidation() == true).
*
* @param useMinimalAPI
* @param isRemoval
* @throws Exception
*/
protected void putFromLoadTest(final boolean useMinimalAPI, boolean isRemoval) throws Exception {
final Object KEY = generateNextKey();
final CountDownLatch writeLatch1 = new CountDownLatch(1);
final CountDownLatch writeLatch2 = new CountDownLatch(1);
final CountDownLatch completionLatch = new CountDownLatch(2);
Thread node1 = new Thread(() -> {
try {
SharedSessionContractImplementor session = mockedSession();
withTx(localEnvironment, session, () -> {
assertNull(localAccessStrategy.get(session, KEY, session.getTimestamp()));
writeLatch1.await();
if (useMinimalAPI) {
localAccessStrategy.putFromLoad(session, KEY, VALUE1, session.getTimestamp(), 1, true);
} else {
localAccessStrategy.putFromLoad(session, KEY, VALUE1, session.getTimestamp(), 1);
}
doUpdate(localAccessStrategy, session, KEY, VALUE2, 2);
return null;
});
} catch (Exception e) {
log.error("node1 caught exception", e);
node1Exception = e;
} catch (AssertionFailedError e) {
node1Failure = e;
} finally {
// Let node2 write
writeLatch2.countDown();
completionLatch.countDown();
}
});
Thread node2 = new Thread(() -> {
try {
SharedSessionContractImplementor session = mockedSession();
withTx(remoteEnvironment, session, () -> {
assertNull(remoteAccessStrategy.get(session, KEY, session.getTimestamp()));
// Let node1 write
writeLatch1.countDown();
// Wait for node1 to finish
writeLatch2.await();
if (useMinimalAPI) {
remoteAccessStrategy.putFromLoad(session, KEY, VALUE1, session.getTimestamp(), 1, true);
} else {
remoteAccessStrategy.putFromLoad(session, KEY, VALUE1, session.getTimestamp(), 1);
}
return null;
});
} catch (Exception e) {
log.error("node2 caught exception", e);
node2Exception = e;
} catch (AssertionFailedError e) {
node2Failure = e;
} finally {
completionLatch.countDown();
}
});
node1.setDaemon(true);
node2.setDaemon(true);
CountDownLatch remoteUpdate = expectAfterUpdate();
node1.start();
node2.start();
assertTrue("Threads completed", completionLatch.await(2, TimeUnit.SECONDS));
assertThreadsRanCleanly();
assertTrue("Update was replicated", remoteUpdate.await(2, TimeUnit.SECONDS));
SharedSessionContractImplementor s1 = mockedSession();
assertEquals(isRemoval ? null : VALUE2, localAccessStrategy.get(s1, KEY, s1.getTimestamp()));
SharedSessionContractImplementor s2 = mockedSession();
Object remoteValue = remoteAccessStrategy.get(s2, KEY, s2.getTimestamp());
if (isUsingInvalidation() || isRemoval) {
// invalidation command invalidates pending put
assertNull(remoteValue);
} else {
// The node1 update is replicated, preventing the node2 PFER
assertEquals(VALUE2, remoteValue);
}
}
use of org.hibernate.engine.spi.SharedSessionContractImplementor in project hibernate-orm by hibernate.
the class PutFromLoadValidatorUnitTest method invalidationBlocksForInProgressPutTest.
private void invalidationBlocksForInProgressPutTest(final boolean keyOnly) throws Exception {
final PutFromLoadValidator testee = new PutFromLoadValidator(cache, regionFactory(cm));
final CountDownLatch removeLatch = new CountDownLatch(1);
final CountDownLatch pferLatch = new CountDownLatch(1);
final AtomicReference<Object> cache = new AtomicReference<>("INITIAL");
Callable<Boolean> pferCallable = () -> {
long txTimestamp = TIME_SERVICE.wallClockTime();
SharedSessionContractImplementor session = mock(SharedSessionContractImplementor.class);
testee.registerPendingPut(session, KEY1, txTimestamp);
PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(session, KEY1, txTimestamp);
if (lock != null) {
try {
removeLatch.countDown();
pferLatch.await();
cache.set("PFER");
return Boolean.TRUE;
} finally {
testee.releasePutFromLoadLock(KEY1, lock);
}
}
return Boolean.FALSE;
};
Callable<Void> invalidateCallable = () -> {
removeLatch.await();
if (keyOnly) {
SharedSessionContractImplementor session = mock(SharedSessionContractImplementor.class);
testee.beginInvalidatingKey(session, KEY1);
} else {
testee.beginInvalidatingRegion();
}
cache.set(null);
return null;
};
ExecutorService executor = Executors.newCachedThreadPool();
cleanup.add(() -> executor.shutdownNow());
Future<Boolean> pferFuture = executor.submit(pferCallable);
Future<Void> invalidateFuture = executor.submit(invalidateCallable);
expectException(TimeoutException.class, () -> invalidateFuture.get(1, TimeUnit.SECONDS));
pferLatch.countDown();
assertTrue(pferFuture.get(5, TimeUnit.SECONDS));
invalidateFuture.get(5, TimeUnit.SECONDS);
assertNull(cache.get());
}
use of org.hibernate.engine.spi.SharedSessionContractImplementor in project hibernate-orm by hibernate.
the class PutFromLoadValidatorUnitTest method registeredPutWithInterveningRemovalTest.
private void registeredPutWithInterveningRemovalTest(final boolean transactional, final boolean removeRegion) throws Exception {
PutFromLoadValidator testee = new PutFromLoadValidator(cache, regionFactory(cm));
try {
long txTimestamp = TIME_SERVICE.wallClockTime();
if (transactional) {
tm.begin();
}
SharedSessionContractImplementor session1 = mock(SharedSessionContractImplementor.class);
SharedSessionContractImplementor session2 = mock(SharedSessionContractImplementor.class);
testee.registerPendingPut(session1, KEY1, txTimestamp);
if (removeRegion) {
testee.beginInvalidatingRegion();
} else {
testee.beginInvalidatingKey(session2, KEY1);
}
PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(session1, KEY1, txTimestamp);
try {
assertNull(lock);
} finally {
if (lock != null) {
testee.releasePutFromLoadLock(KEY1, lock);
}
if (removeRegion) {
testee.endInvalidatingRegion();
} else {
testee.endInvalidatingKey(session2, KEY1);
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
use of org.hibernate.engine.spi.SharedSessionContractImplementor in project hibernate-orm by hibernate.
the class PutFromLoadValidatorUnitTest method multipleRegistrationtest.
private void multipleRegistrationtest(final boolean transactional) throws Exception {
final PutFromLoadValidator testee = new PutFromLoadValidator(cache, regionFactory(cm));
final CountDownLatch registeredLatch = new CountDownLatch(3);
final CountDownLatch finishedLatch = new CountDownLatch(3);
final AtomicInteger success = new AtomicInteger();
Runnable r = () -> {
try {
long txTimestamp = TIME_SERVICE.wallClockTime();
if (transactional) {
tm.begin();
}
SharedSessionContractImplementor session = mock(SharedSessionContractImplementor.class);
testee.registerPendingPut(session, KEY1, txTimestamp);
registeredLatch.countDown();
registeredLatch.await(5, TimeUnit.SECONDS);
PutFromLoadValidator.Lock lock = testee.acquirePutFromLoadLock(session, KEY1, txTimestamp);
if (lock != null) {
try {
log.trace("Put from load lock acquired for key = " + KEY1);
success.incrementAndGet();
} finally {
testee.releasePutFromLoadLock(KEY1, lock);
}
} else {
log.trace("Unable to acquired putFromLoad lock for key = " + KEY1);
}
finishedLatch.countDown();
} catch (Exception e) {
e.printStackTrace();
}
};
ExecutorService executor = Executors.newFixedThreadPool(3);
cleanup.add(() -> executor.shutdownNow());
// Start with a removal so the "isPutValid" calls will fail if
// any of the concurrent activity isn't handled properly
testee.beginInvalidatingRegion();
testee.endInvalidatingRegion();
TIME_SERVICE.advance(1);
// Do the registration + isPutValid calls
executor.execute(r);
executor.execute(r);
executor.execute(r);
assertTrue(finishedLatch.await(5, TimeUnit.SECONDS));
assertEquals("All threads succeeded", 3, success.get());
}
Aggregations