[HHH-4836] (Infinispan: 2L QueryCache don't considers cached queries which belong to current transaction) Fixed by not suspending transactions on get any more, since no locks are aquired on get.

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18790 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Galder Zamarreno 2010-02-12 12:21:43 +00:00
parent 23ee88a55b
commit d88f65ff0c
4 changed files with 57 additions and 20 deletions

View File

@ -194,28 +194,21 @@ public abstract class BaseRegion implements Region {
} }
/** /**
* Performs a JBoss Cache <code>get(Fqn, Object)</code> after first * Performs a Infinispan <code>get(Fqn, Object)</code>
* {@link #suspend suspending any ongoing transaction}. Wraps any exception *
* in a {@link CacheException}. Ensures any ongoing transaction is resumed.
*
* @param key The key of the item to get * @param key The key of the item to get
* @param opt any option to add to the get invocation. May be <code>null</code> * @param opt any option to add to the get invocation. May be <code>null</code>
* @param suppressTimeout should any TimeoutException be suppressed? * @param suppressTimeout should any TimeoutException be suppressed?
* @return The retrieved object * @return The retrieved object
* @throws CacheException issue managing transaction or talking to cache * @throws CacheException issue managing transaction or talking to cache
*/ */
protected Object suspendAndGet(Object key, FlagAdapter opt, boolean suppressTimeout) throws CacheException { protected Object get(Object key, FlagAdapter opt, boolean suppressTimeout) throws CacheException {
Transaction tx = suspend(); if (suppressTimeout)
try { return cacheAdapter.getAllowingTimeout(key);
if (suppressTimeout) else
return cacheAdapter.getAllowingTimeout(key); return cacheAdapter.get(key);
else
return cacheAdapter.get(key);
} finally {
resume(tx);
}
} }
public Object getOwnerForPut() { public Object getOwnerForPut() {
Transaction tx = null; Transaction tx = null;
try { try {

View File

@ -50,12 +50,13 @@ public class QueryResultsRegionImpl extends BaseTransactionalDataRegion implemen
if (!checkValid()) if (!checkValid())
return null; return null;
// Don't hold the JBC node lock throughout the tx, as that // In Infinispan get doesn't acquire any locks, so no need to suspend the tx.
// prevents updates // In the past, when get operations acquired locks, suspending the tx was a way
// 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
return suspendAndGet(key, FlagAdapter.ZERO_LOCK_ACQUISITION_TIMEOUT, true); return get(key, FlagAdapter.ZERO_LOCK_ACQUISITION_TIMEOUT, true);
} }
public void put(Object key, Object value) throws CacheException { public void put(Object key, Object value) throws CacheException {
if (checkValid()) { if (checkValid()) {

View File

@ -58,7 +58,7 @@ public class TimestampsRegionImpl extends BaseGeneralDataRegion implements Times
public Object get(Object key) throws CacheException { public Object get(Object key) throws CacheException {
Object value = localCache.get(key); Object value = localCache.get(key);
if (value == null && checkValid()) { if (value == null && checkValid()) {
value = suspendAndGet(key, null, false); value = get(key, null, false);
if (value != null) if (value != null)
localCache.put(key, value); localCache.put(key, value);
} }

View File

@ -287,4 +287,47 @@ public class BasicTransactionalTestCase extends SingleNodeTestCase {
commitOrRollbackTx(); commitOrRollbackTx();
} }
} }
public void testQueryCacheHitInSameTransaction() throws Exception {
Session s = null;
Item item = new Item("galder", "Galder's Item");
beginTx();
try {
s = openSession();
s.getTransaction().begin();
s.persist(item);
s.getTransaction().commit();
s.close();
} catch (Exception e) {
setRollbackOnlyTx(e);
} finally {
commitOrRollbackTx();
}
beginTx();
try {
s = openSession();
Statistics stats = s.getSessionFactory().getStatistics();
s.createQuery("from Item").setCacheable(true).list();
s.createQuery("from Item").setCacheable(true).list();
assertEquals(1, stats.getQueryCacheHitCount());
s.close();
} catch (Exception e) {
setRollbackOnlyTx(e);
} finally {
commitOrRollbackTx();
}
beginTx();
try {
s = openSession();
s.createQuery("delete from Item").executeUpdate();
s.close();
} catch (Exception e) {
setRollbackOnlyTx(e);
} finally {
commitOrRollbackTx();
}
}
} }