These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: Deadlock using Hibernate with transactional TreeCache 1.3.0
PostPosted: Tue Jul 04, 2006 10:18 am 
Newbie

Joined: Tue Jul 04, 2006 9:58 am
Posts: 15
Hibernate version:3.1.3, 3.2CR2

Full stack trace of any exception that occurs:
2006-07-04 17:11:28,320 ERROR [org.jboss.cache.lock.IdentityLock] read lock for /com/offshorecreations/nlop/admin/domain/Round/com.offshorecreations.nlop.admin.domain.Round#1764208 could not be acquired by GlobalTransaction:<192.168.3.6:4813>:3 after 30000 ms. Locks: Read lock owners: []
Write lock owner: GlobalTransaction:<192.168.3.6:4813>:1
, lock info: write owner=GlobalTransaction:<192.168.3.6:4813>:1 (org.jboss.cache.lock.LockStrategyReadCommitted@4ad26103)
2006-07-04 17:11:28,320 DEBUG [org.jboss.cache.Node] failure acquiring lock: fqn=/com/offshorecreations/nlop/admin/domain/Round/com.offshorecreations.nlop.admin.domain.Round#1764208, caller=GlobalTransaction:<192.168.3.6:4813>:3, lock=write owner=GlobalTransaction:<192.168.3.6:4813>:1 (org.jboss.cache.lock.LockStrategyReadCommitted@4ad26103)
2006-07-04 17:11:28,320 INFO [org.jboss.cache.interceptors.TxInterceptor] There was a problem handling this request
org.jboss.cache.lock.TimeoutException: failure acquiring lock: fqn=/com/offshorecreations/nlop/admin/domain/Round/com.offshorecreations.nlop.admin.domain.Round#1764208, caller=GlobalTransaction:<192.168.3.6:4813>:3, lock=write owner=GlobalTransaction:<192.168.3.6:4813>:1 (org.jboss.cache.lock.LockStrategyReadCommitted@4ad26103)
at org.jboss.cache.Node.acquire(Node.java:407)
at org.jboss.cache.interceptors.PessimisticLockInterceptor.lock(PessimisticLockInterceptor.java:231)
at org.jboss.cache.interceptors.PessimisticLockInterceptor.invoke(PessimisticLockInterceptor.java:166)
at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
at org.jboss.cache.interceptors.UnlockInterceptor.invoke(UnlockInterceptor.java:32)
at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
at org.jboss.cache.interceptors.ReplicationInterceptor.invoke(ReplicationInterceptor.java:34)
at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
at org.jboss.cache.interceptors.TxInterceptor.handleNonTxMethod(TxInterceptor.java:345)
at org.jboss.cache.interceptors.TxInterceptor.invoke(TxInterceptor.java:156)
at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
at org.jboss.cache.interceptors.CacheMgmtInterceptor.invoke(CacheMgmtInterceptor.java:138)
at org.jboss.cache.TreeCache.invokeMethod(TreeCache.java:5517)
at org.jboss.cache.TreeCache.get(TreeCache.java:3468)
at org.jboss.cache.TreeCache.get(TreeCache.java:3449)
at org.hibernate.cache.TreeCache.read(TreeCache.java:54)
at org.hibernate.cache.TransactionalCache.get(TransactionalCache.java:31)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromSecondLevelCache(DefaultLoadEventListener.java:457)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:333)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:122)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:162)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:86)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:871)
at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:839)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:266)
at org.hibernate.type.EntityType.resolve(EntityType.java:303)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:116)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:842)
at org.hibernate.loader.Loader.doQuery(Loader.java:717)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1785)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:48)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:42)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:2821)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:370)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:351)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:122)
at org.hibernate.event.def.DefaultLoadEventListener.lockAndLoad(DefaultLoadEventListener.java:277)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:89)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:871)
at org.hibernate.impl.SessionImpl.load(SessionImpl.java:852)
at org.hibernate.impl.SessionImpl.load(SessionImpl.java:847)
at org.springframework.orm.hibernate3.HibernateTemplate$3.doInHibernate(HibernateTemplate.java:486)
at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:365)
at org.springframework.orm.hibernate3.HibernateTemplate.load(HibernateTemplate.java:483)
at com.offshorecreations.nlop.admin.integration.dao.OccasionDao.loadOccasion(OccasionDao.java:41)
at com.offshorecreations.nlop.admin.service.TournamentService.checkOccasion4Checkin(TournamentService.java:759)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:335)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:181)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:148)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
at $Proxy42.checkOccasion4Checkin(Unknown Source)
at com.offshorecreations.nlop.admin.service.PeriodicalService.checkAndSetTournamentCanceling(PeriodicalService.java:835)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:335)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:181)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:148)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
at $Proxy46.checkAndSetTournamentCanceling(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:248)
at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:165)
at com.offshorecreations.nlop.admin.common.MethodInvokingJob.executeInternal(MethodInvokingJob.java:62)
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:66)
at org.quartz.core.JobRunShell.run(JobRunShell.java:203)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520)
Caused by: org.jboss.cache.lock.TimeoutException: read lock for /com/offshorecreations/nlop/admin/domain/Round/com.offshorecreations.nlop.admin.domain.Round#1764208 could not be acquired by GlobalTransaction:<192.168.3.6:4813>:3 after 30000 ms. Locks: Read lock owners: []
Write lock owner: GlobalTransaction:<192.168.3.6:4813>:1
, lock info: write owner=GlobalTransaction:<192.168.3.6:4813>:1 (org.jboss.cache.lock.LockStrategyReadCommitted@4ad26103)
at org.jboss.cache.lock.IdentityLock.acquireReadLock(IdentityLock.java:257)
at org.jboss.cache.Node.acquireReadLock(Node.java:417)
at org.jboss.cache.Node.acquire(Node.java:384)
... 79 more
2006-07-04 17:11:28,320 INFO [org.hibernate.event.def.DefaultLoadEventListener] Error performing load command
org.hibernate.cache.CacheException: org.jboss.cache.lock.TimeoutException: failure acquiring lock: fqn=/com/offshorecreations/nlop/admin/domain/Round/com.offshorecreations.nlop.admin.domain.Round#1764208, caller=GlobalTransaction:<192.168.3.6:4813>:3, lock=write owner=GlobalTransaction:<192.168.3.6:4813>:1 (org.jboss.cache.lock.LockStrategyReadCommitted@4ad26103)
at org.hibernate.cache.TreeCache.read(TreeCache.java:57)
at org.hibernate.cache.TransactionalCache.get(TransactionalCache.java:31)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromSecondLevelCache(DefaultLoadEventListener.java:457)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:333)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:122)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:162)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:86)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:871)
at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:839)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:266)
at org.hibernate.type.EntityType.resolve(EntityType.java:303)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:116)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:842)
at org.hibernate.loader.Loader.doQuery(Loader.java:717)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1785)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:48)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:42)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:2821)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:370)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:351)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:122)
at org.hibernate.event.def.DefaultLoadEventListener.lockAndLoad(DefaultLoadEventListener.java:277)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:89)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:871)
at org.hibernate.impl.SessionImpl.load(SessionImpl.java:852)
at org.hibernate.impl.SessionImpl.load(SessionImpl.java:847)
at org.springframework.orm.hibernate3.HibernateTemplate$3.doInHibernate(HibernateTemplate.java:486)
at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:365)
at org.springframework.orm.hibernate3.HibernateTemplate.load(HibernateTemplate.java:483)
at com.offshorecreations.nlop.admin.integration.dao.OccasionDao.loadOccasion(OccasionDao.java:41)
at com.offshorecreations.nlop.admin.service.TournamentService.checkOccasion4Checkin(TournamentService.java:759)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:335)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:181)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:148)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
at $Proxy42.checkOccasion4Checkin(Unknown Source)
at com.offshorecreations.nlop.admin.service.PeriodicalService.checkAndSetTournamentCanceling(PeriodicalService.java:835)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:335)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:181)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:148)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
at $Proxy46.checkAndSetTournamentCanceling(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:248)
at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:165)
at com.offshorecreations.nlop.admin.common.MethodInvokingJob.executeInternal(MethodInvokingJob.java:62)
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:66)
at org.quartz.core.JobRunShell.run(JobRunShell.java:203)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520)
Caused by: org.jboss.cache.lock.TimeoutException: failure acquiring lock: fqn=/com/offshorecreations/nlop/admin/domain/Round/com.offshorecreations.nlop.admin.domain.Round#1764208, caller=GlobalTransaction:<192.168.3.6:4813>:3, lock=write owner=GlobalTransaction:<192.168.3.6:4813>:1 (org.jboss.cache.lock.LockStrategyReadCommitted@4ad26103)
at org.jboss.cache.Node.acquire(Node.java:407)
at org.jboss.cache.interceptors.PessimisticLockInterceptor.lock(PessimisticLockInterceptor.java:231)
at org.jboss.cache.interceptors.PessimisticLockInterceptor.invoke(PessimisticLockInterceptor.java:166)
at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
at org.jboss.cache.interceptors.UnlockInterceptor.invoke(UnlockInterceptor.java:32)
at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
at org.jboss.cache.interceptors.ReplicationInterceptor.invoke(ReplicationInterceptor.java:34)
at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
at org.jboss.cache.interceptors.TxInterceptor.handleNonTxMethod(TxInterceptor.java:345)
at org.jboss.cache.interceptors.TxInterceptor.invoke(TxInterceptor.java:156)
at org.jboss.cache.interceptors.Interceptor.invoke(Interceptor.java:68)
at org.jboss.cache.interceptors.CacheMgmtInterceptor.invoke(CacheMgmtInterceptor.java:138)
at org.jboss.cache.TreeCache.invokeMethod(TreeCache.java:5517)
at org.jboss.cache.TreeCache.get(TreeCache.java:3468)
at org.jboss.cache.TreeCache.get(TreeCache.java:3449)
at org.hibernate.cache.TreeCache.read(TreeCache.java:54)
... 64 more
Caused by: org.jboss.cache.lock.TimeoutException: read lock for /com/offshorecreations/nlop/admin/domain/Round/com.offshorecreations.nlop.admin.domain.Round#1764208 could not be acquired by GlobalTransaction:<192.168.3.6:4813>:3 after 30000 ms. Locks: Read lock owners: []
Write lock owner: GlobalTransaction:<192.168.3.6:4813>:1
, lock info: write owner=GlobalTransaction:<192.168.3.6:4813>:1 (org.jboss.cache.lock.LockStrategyReadCommitted@4ad26103)
at org.jboss.cache.lock.IdentityLock.acquireReadLock(IdentityLock.java:257)
at org.jboss.cache.Node.acquireReadLock(Node.java:417)
at org.jboss.cache.Node.acquire(Node.java:384)
... 79 more

Name and version of the database you are using:
PostgreSQL 8.0.1

++++++++++++++++++++
+++++ DESCRIPTION +++++
++++++++++++++++++++

It seems like we discovered an unpredictable Hibernate and/or TreeCache behavior after upgrade JBossCache from 1.2.4SP2 to JBossCache 1.3.0SP2. For now I can witness that the same problem appears with 1.4.0CR2. I do not think that it’s Hibernate-only or TreeCache-only issue but I do think it’s a kind of integration issue or misunderstanding of how TreeCache transaction isolation is implemented.



Our application works in clustered environment and we use JBossCache as L2 cache solution for Hibernate 3.1.3 (I checked this with 3.2.0CR2 as well). Our settings for JBossCache are

REPL_SYNC, READ_COMMITED and our target business object methods (f1 and f2) have PROPAGATION_REQUIRED and PROPAGATION_REQUIRES_NEW. Our JDBC driver is 3.0 compliant.

Our objects hierarchy is like: Occasion contains link to Round and Round contains link to Tournament. Round is NOT configured as “lazy” field in Occasion mapping b/c we always need to have it initialized.



Here is in short what we try to do in our application:



(1) Transaction1: Call f1 (PROPAGATION_REQUIRED) method of a business object and it causes Occasion1 to be loaded via a cachable query. After that Hibernate initializes Occasion1.round field and loads Round1.

(2) Transaction1: Hibernate puts loaded Occasion1 and Round1 in L2 cache.

(3) Transaction1: TreeCache creates com/companyname/Occasion/com.companyname.Occasion#1 region and obtains WriteLock (WL1)

(4) Transaction1: TreeCache creates com/companyname/Round/com.companyname.Round#1 region and obtains WriteLock (WL2)

(5) Transaction1: Do some business logic stuff

(6) Transaction1: We expect current transaction to be long and we want to change status of Occasoin1 in DB very quickly. At this point we need an exclusive lock for appropriate row in DB table to change the status and commit it. In order to do this we call f2 (PROPAGATION_REQUIRES_NEW) which suppose to be a REALLY short transaction which release lock on the DB row as fast as possible.



(7) Transaction2: Transaction1 SUSPENDED at this point. We call HibernateTemplate (we use Spring as well) to load Occasion1 for update with LockMode.UPGRADE flag and get exclusive lock.

(8) Transaction2: Hibernate does NOT check for an instance of Occasion1 in L2 cache ( I suppose it’s b/c we obviously do want to lock it for update )

(9) Transaction2: Hibernate does check for an instance of Round1 in L2 cache and it calls get() on TreeCache to obtain com/companyname/Round/com.companyname.Round#1

(10) Transaction2: At this point 1.3.0SP2 tries to obtain ReadLock for com/companyname/Round/com.companyname.Round#1 and it can’t b/c there is a WL for that node in suspended Transaction1 !!! It can’t obtain ReadLock for Round#1 anyhow!

(11) Transaction2: Stuck waiting for WL2 to be released in TreeCache but it can’t be released as soon as Transaction1 suspended and waits for Transaction2 to finish.



Obviously this situation is ridiculous – a legal sequence of operations causes a deadlock on TreeCache. We do not expect com/companyname/Round/com.companyname.Round#1 to be visible in Transaction2 b/c we use READ_COMMITED but WL2 must not affect Transaction2 in this way. As soon as TreeCache prevents other transactions from reading com/companyname/Round/com.companyname.Round#1 it must not tell other transactions that the node exists to keep READ_COMMITED behavior consistent. For now it simply preventing everybody from using PROPAGATION_REQUIRES_NEW.

The described scenario works with 1.2.4SP2 without a problem and I have serious concern that READ_COMMITED strategy is really implemented in v1.2.4 but at least the behavior is more consistent comparing to v1.3.0.



We tried to change PROPAGATION_REQUIRES_NEW to PROPAGATION_NESTED and take advantage of nested transactions. We assume that com/companyname/Round/com.companyname.Round#1 would be available in a nested Transaction2 from Transaction1. But PROPAGATION_NESTED isn’t supported by current JBossTransaction implementation (see line 209 in TxManager.java from 4.0.4.GA).

We could change isolation to READ_UNCOMMITED but it’s simply impossible in many other places of our application.

We could make a trick and load Occasion1 with Round1 in a separate Transaction0 before starting Transaction1 but we HAVE to use LRU policy. That is why there is no chance for us to make sure that eviction won’t happen between Transaction0 and Transaction1. If it happened then we are in the same situation as described above.

Finally we could stop using Transaction2 but our application is intend to handle large amount of traffic and as soon as Transaction1 takes up to 3sec (comparing to 50ms for Transaction2) we might get up to 700-1000 transactions on queue waiting for table row lock to be released and we just can’t allow this.



From what I see in Hibernate TreeCache sources and I have no idea how to avoid the situation described above. One of my developers told me that probably it’s possible to put stuff into L2 cache on transaction commit which would decrease WL time and resolve the issue with the deadlock. Honestly I’m seriously concerned how it applies to existing Hibernate. I think small issues like performance issue of loading the same object during 1 transaction more then once can be resolved by using L1 cache or JDBC driver abilities. But I guess there are a plenty of work to make this working for cachable queries.

Another option I see is to do a trick and put values for Round1 and Occasion1 into a new region for Transaction2 if we know that Transaction1 suspended and owns WLs for various nodes. I really do not like this way b/c in fact it’s not a pure pessimistic locking. But the issue described before is worse price for “pure“ READ_COMMITED strategy. In fact it showstopper assuming there is no way to use PROPAGATION_NESTED.



Probably I’m not a first person reported this issues (I can’t call a defect). I would like to check if you have any suggestions about how to resolve it or how to make a workaround for this.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 08, 2006 7:18 am 
Newbie

Joined: Tue Jul 04, 2006 9:58 am
Posts: 15
I tried to figure out about nested transactions as a replacement for REQUIRES_NEW in my test case. Scott M Stark helped me to realize that latest JBossTS declares support of nested trans.

Unfortunatelly the latest implementation of JBossTS from http://labs.jboss.com/portal/jbosstm/downloads doesn't implement PROPAGATION_NESTED transaction semantic. Tested versions: JBoss 4.0.3SP1, jbossts-jta-4.2.1Beta1.zip, Hibernate 3.2CR2, TreeCache 1.3.0SP2, JDBC3.0 compliant driver and PostgreSQL 8.0.2

Here is a sample illustrating my point:
    (1) I start global tx1 from Spring method call f1() with PROPAGATION_REQUIRED. It registered in gtx table with number 1
    (2) tx1 got associated with an opened Hibernate session
    (3) invokes Hibernate DAOs to load some domain objects
    (4) tx1 calls f2() with PROPAGATION_NESTED
    (4.2) No new transaction created in gtx
    (5) f2 invokes Hibernate DAO to load 1 domain O1 object and resave it with 1 field updated.
    (6) After f2 exit and execution point is back in f1() no commit done for O1 and no record data flushed to DB.


Expected behavior is that after step 5 the nested transaction will be commited and hibernate session object O1 (modified within f2) call will be flushed and DB record updated.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 11, 2006 6:17 am 
Newbie

Joined: Tue Jul 11, 2006 6:14 am
Posts: 2
See http://jira.jboss.com/jira/browse/JBCACHE-679 for a unit test submitted by user that demos this problem

_________________
--
Manik Surtani
Lead, JBoss Cache
http://labs.jboss.com/jbosscache


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 11, 2006 6:23 am 
Newbie

Joined: Tue Jul 04, 2006 9:58 am
Posts: 15
Thanks Manik! Please let me know if you need me to comment something about the test.

manik.surtani@jboss.com wrote:
See http://jira.jboss.com/jira/browse/JBCACHE-679 for a unit test submitted by user that demos this problem


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 13, 2006 2:27 am 
Newbie

Joined: Tue Jul 04, 2006 9:58 am
Posts: 15
Hi!

Any luck with reproducing the problem using the test case?

Thanks!

manik.surtani@jboss.com wrote:
See http://jira.jboss.com/jira/browse/JBCACHE-679 for a unit test submitted by user that demos this problem


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 22, 2006 10:12 am 
Newbie

Joined: Tue Jul 04, 2006 9:58 am
Posts: 15
I just curious if there any news about this...


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.