Hi
I have application, where 2 threads are trying execute the same cached query. Second query fails with message
org.springframework.orm.hibernate3.HibernateSystemException: org.jboss.cache.lock.UpgradeException: upgrade lock for (...) could not be acquired after 2 ms. Lock map ownership Read lock owners: []
Write lock owner: GlobalTransaction:<10.82.33.235:7900>:37 (caller=GlobalTransaction:<10.82.33.235:7900>:38, lock info: write owner=GlobalTransaction:<10.82.33.235:7900>:37 (org.jboss.cache.lock.LockStrategyReadCommitted@1cd9f1aa)); nested exception is org.hibernate.cache.CacheException: org.jboss.cache.lock.UpgradeException: upgrade lock for (..) could not be acquired after 2 ms. Lock map ownership Read lock owners: []
Write lock owner: GlobalTransaction:<10.82.33.235:7900>:37
(caller=GlobalTransaction:<10.82.33.235:7900>:38, lock info: write owner=GlobalTransaction:<10.82.33.235:7900>:37 (org.jboss.cache.lock.LockStrategyReadCommitted@1cd9f1aa))
(..)
at org.hibernate.cache.jbc2.util.CacheHelper.putAllowingTimeout(CacheHelper.java:245)
at org.hibernate.cache.jbc2.query.QueryResultsRegionImpl.put(QueryResultsRegionImpl.java:130)
(..)
LockAcquisitionTimeout for all my caches is set to 15000, so why timeout valyue in StackTrace is set to 2ms?
I do some investigation and found, that QueryResultsRegionImpl.put has comments:
// Add a zero (or quite low) timeout option so we don't block.
// Ignore any TimeoutException. Basically we forego caching the
// query result in order to avoid blocking.
and custom very low timeout (2ms) is set. But when UpgradeException (caused by lock acquisition timeout) is thrown instead of TimeoutException
why is NOT really ignored? When we looks into CacheHelper.putAllowingTimeout we can see:
Code:
public static void putAllowingTimeout(Cache cache, Fqn region, Object key, Object value, Option option) throws CacheException {
try {
setInvocationOption(cache, option);
cache.put(new Fqn(region, key), ITEM, value);
}
catch (TimeoutException allowed) {
// ignore it
}
catch (Exception e) {
throw new CacheException(e);
}
}
We can see, that only TimeoutException is ignored! But in treecache world there is another exception LockingException, and javadocs for this exception says:
Code:
/**
* Used for all locking-related exceptions, e.g. when a lock could not be
* acquired within the timeout, or when a deadlock was detected or an upgrade failed.
*
* @author <a href="mailto:bela@jboss.org">Bela Ban</a>.
*/
public class LockingException extends CacheException
So, should be LockingException ignored in CacheHelper.putAllowingTimeout/getAllowingTimeout ? Now it's impossible to run 2 (or more) parallels cacheables queries without exception (using pessimistic locking scheme).
Hibernate 3.3.1.GA +JBossCache+3.1.0.GA (PESSIMISTIC)