HHH-10005 Query in context needs precedence over query in cache

This commit is contained in:
Radim Vansa 2015-07-30 17:28:52 +02:00
parent 44e7171edd
commit ab4c6841df
2 changed files with 78 additions and 12 deletions

View File

@ -123,18 +123,18 @@ public class QueryResultsRegionImpl extends BaseTransactionalDataRegion implemen
// to avoid holding locks that would prevent updates.
// Add a zero (or low) timeout option so we don't block
// waiting for tx's that did a put to commit
Object result;
Object result = null;
Map map = transactionContext.get(session);
if (map != null) {
result = map.get(key);
}
if (result == null) {
if ( skipCacheStore ) {
result = getCache.withFlags( Flag.SKIP_CACHE_STORE ).get( key );
}
else {
result = getCache.get( key );
}
if (result == null) {
Map map = transactionContext.get(session);
if (map != null) {
result = map.get(key);
}
}
return result;
}

View File

@ -11,6 +11,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
import org.hibernate.Session;
@ -102,7 +103,7 @@ public class QueryRegionImplTestCase extends AbstractGeneralDataRegionTestCase {
@Override
public void run() {
try {
assertNotEquals(VALUE2, callWithSession(sessionFactory, session-> region.get(session, KEY)));
assertNotEquals(VALUE2, callWithSession(sessionFactory, session -> region.get(session, KEY)));
} catch (AssertionFailedError e) {
holder.addAssertionFailure(e);
} catch (Exception e) {
@ -118,7 +119,7 @@ public class QueryRegionImplTestCase extends AbstractGeneralDataRegionTestCase {
public void run() {
try {
withSession(sessionFactory, session -> {
region.put((SessionImplementor) session, KEY, VALUE2);
region.put(session, KEY, VALUE2);
writerLatch.await();
});
} catch (Exception e) {
@ -143,7 +144,7 @@ public class QueryRegionImplTestCase extends AbstractGeneralDataRegionTestCase {
assertTrue("Reader finished promptly", completionLatch.await(100, TimeUnit.MILLISECONDS));
assertEquals(VALUE2, region.get(null, KEY));
assertEquals(VALUE2, callWithSession(sessionFactory, session -> region.get(session, KEY)));
});
}
@ -313,6 +314,71 @@ public class QueryRegionImplTestCase extends AbstractGeneralDataRegionTestCase {
});
}
@Test
public void testQueryUpdate() throws Exception {
withQueryRegion((sessionFactory, region) -> {
ExceptionHolder holder = new ExceptionHolder();
CyclicBarrier barrier = new CyclicBarrier(2);
withSession(sessionFactory, session -> region.put(session, KEY, VALUE1));
Thread updater = new Thread() {
@Override
public void run() {
try {
withSession(sessionFactory, (session) -> {
assertEquals(VALUE1, region.get(session, KEY));
region.put(session, KEY, VALUE2);
assertEquals(VALUE2, region.get(session, KEY));
barrier.await(5, TimeUnit.SECONDS);
barrier.await(5, TimeUnit.SECONDS);
region.put(session, KEY, VALUE3);
assertEquals(VALUE3, region.get(session, KEY));
barrier.await(5, TimeUnit.SECONDS);
barrier.await(5, TimeUnit.SECONDS);
});
} catch (AssertionFailedError e) {
holder.addAssertionFailure(e);
barrier.reset();
} catch (Exception e) {
holder.addException(e);
barrier.reset();
}
}
};
Thread reader = new Thread() {
@Override
public void run() {
try {
withSession(sessionFactory, (session) -> {
assertEquals(VALUE1, region.get(session, KEY));
barrier.await(5, TimeUnit.SECONDS);
assertEquals(VALUE1, region.get(session, KEY));
barrier.await(5, TimeUnit.SECONDS);
barrier.await(5, TimeUnit.SECONDS);
assertEquals(VALUE1, region.get(session, KEY));
barrier.await(5, TimeUnit.SECONDS);
});
} catch (AssertionFailedError e) {
holder.addAssertionFailure(e);
barrier.reset();
} catch (Exception e) {
holder.addException(e);
barrier.reset();
}
}
};
updater.start();
reader.start();
updater.join();
reader.join();
holder.checkExceptions();
assertEquals(VALUE3, callWithSession(sessionFactory, session -> region.get(session, KEY)));
});
}
@Listener
public class GetBlocker {
private final CountDownLatch latch;