mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-17 08:35:13 +00:00
HHH-10005 Query in context needs precedence over query in cache
This commit is contained in:
parent
44e7171edd
commit
ab4c6841df
@ -123,18 +123,18 @@ public Object get(SessionImplementor session, Object key) throws CacheException
|
|||||||
// to avoid holding locks that would prevent updates.
|
// to avoid holding locks that would prevent updates.
|
||||||
// Add a zero (or low) timeout option so we don't block
|
// Add a zero (or low) timeout option so we don't block
|
||||||
// waiting for tx's that did a put to commit
|
// 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 ) {
|
if ( skipCacheStore ) {
|
||||||
result = getCache.withFlags( Flag.SKIP_CACHE_STORE ).get( key );
|
result = getCache.withFlags( Flag.SKIP_CACHE_STORE ).get( key );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = getCache.get( key );
|
result = getCache.get( key );
|
||||||
}
|
}
|
||||||
if (result == null) {
|
|
||||||
Map map = transactionContext.get(session);
|
|
||||||
if (map != null) {
|
|
||||||
result = map.get(key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.CyclicBarrier;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
@ -102,7 +103,7 @@ public void testPutDoesNotBlockGet() throws Exception {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
assertNotEquals(VALUE2, callWithSession(sessionFactory, session-> region.get(session, KEY)));
|
assertNotEquals(VALUE2, callWithSession(sessionFactory, session -> region.get(session, KEY)));
|
||||||
} catch (AssertionFailedError e) {
|
} catch (AssertionFailedError e) {
|
||||||
holder.addAssertionFailure(e);
|
holder.addAssertionFailure(e);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -118,7 +119,7 @@ public void run() {
|
|||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
withSession(sessionFactory, session -> {
|
withSession(sessionFactory, session -> {
|
||||||
region.put((SessionImplementor) session, KEY, VALUE2);
|
region.put(session, KEY, VALUE2);
|
||||||
writerLatch.await();
|
writerLatch.await();
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -143,7 +144,7 @@ public void run() {
|
|||||||
|
|
||||||
assertTrue("Reader finished promptly", completionLatch.await(100, TimeUnit.MILLISECONDS));
|
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 void run() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@Listener
|
||||||
public class GetBlocker {
|
public class GetBlocker {
|
||||||
private final CountDownLatch latch;
|
private final CountDownLatch latch;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user