|
From: Dave B. <dba...@on...> - 2005-05-20 20:35:44
|
Hi Juergen, I have patched my Spring 1.2 with your updated SessionFactoryUtils and SessionHolder, and switched over to JtaTransactionManager. Seems to fix this problem. Thanks for your help, Dave PS: I found another race condition with timeouts. I will post in a separate email. Juergen Hoeller wrote: >You don't need to use WebLogicJtaTransactionManager unless you intend to >leverage WebLogic-specific (7.0+) JTA extensions. A plain >JtaTransactionManager should be sufficient for typical usage. If you need >transaction suspension, specify the corresponding "transactionManagerName" >(see JtaTransactionManager's javadoc): this will enable >PROPAGATION_REQUIRES_NEW and PROPAGATION_NOT_SUPPORTED. > >You could try to patch 1.1.5 accordingly, but I would recommend to use an >upcoming nightly build or wait for 1.2.1 (which is scheduled for next >Friday). > >Juergen > > >-----Original Message----- >From: spr...@li... >[mailto:spr...@li...]On Behalf >Of Dave Ballard >Sent: Friday, May 20, 2005 7:20 PM >To: spr...@li... >Subject: Re: [Springframework-developer] Race condition with transaction >synchronization? > > >Hi Juergen, > >Thanks for looking into this and providing an insightful description of >the problem. For me, this mix of EJB CMT and Spring tx demarcation is >only a temporary situation as I transition away from EJB. I've got a >service methods that are called from both the web tier (need Spring to >start a transaction) and from a SLSB (EJB CMT starts transaction). > >My problem now is that Spring 1.2's WebLogicJtaTransactionManager is not >compatible with WebLogic 6.1 >(org.springframework.transaction.TransactionSystemException: Could not >initialize WebLogicJtaTransactionManager because WebLogic API classes >are not available; nested exception is java.lang.ClassNotFoundException: >weblogic.transaction.UserTransaction.). > >Do you think that your fix below is something that could be patched into >1.1.5? I'll do it, but I don't want to waste my time if you don't think >that it is a good idea. > >Thanks, >Dave > >Juergen Hoeller wrote: > > > >>Hi Dave, >> >>I've just verified that your scenario can indeed lead to broken cleanup: >> >>If the rollback gets triggered from some other thread (i.e. not the thread >>that created the transaction), the Hibernate SessionHolder cannot get >>removed from the original thread. That is actually already expected, as it >>can also happen in case of remote transaction propagation: Spring will >>simply remove the current Hibernate Session from the SessionHolder in this >>case, and reuse the SessionHolder when another transaction gets executed on >>that thread. >> >>However, the above only works with direct JTA Session synchronization only. >>If Spring transaction synchronization is involved too (that is, if >>transactions get initiated from either EJB CMT or Spring transaction >>demarcation, not just from EJB CMT), an IllegalStateException will be >> >> >thrown > > >>whenever a thread with such an empty SessionHolder is supposed to execute a >>Spring-driven transaction. This is straightforward to reproduce in a test >>case. >> >>I've just fixed this issue for both Hibernate 2.1 and Hibernate3, to be >>committed today. The fix should be available in the next nightly build, and >>will be released in Spring 1.2.1. >> >>Note that it's generally recommended to use *either* EJB CMT *or* >>Spring-driven transactions. Spring's Session synchronization for Hibernate >>will work nicely with EJB CMT only, without any Spring transaction >>demarcation involved. Mixing both is nevertheless valid, therefore the >> >> >above > > >>fix is necessary. >> >>Thanks for reporting this! >> >>Juergen >> >> >>-----Original Message----- >>From: spr...@li... >>[mailto:spr...@li...]On Behalf >>Of Dave Ballard >>Sent: Wednesday, May 18, 2005 10:41 PM >>To: spr...@li... >>Subject: Re: [Springframework-developer] Race condition with transaction >>synchronization? >> >> >>Hello, >> >>Sorry to respond to my own post, but if there's someone out there that >>is familiar with SessionFactoryUtils, I would appreciate a little of >>your time to discuss this issue. This appears to be a bug in the JTA >>session synchronization code for hibernate. >> >>Thanks, >>Dave >> >>Dave Ballard wrote: >> >> >> >> >> >>>Hello, >>> >>>I posted this on the forums, but costin and Rod suggested that I post >>>it here. >>> >>>I'm using Spring Framework 1.1.5 with Hibernate on WebLogic Server >>>6.1. I'm testing timeout scenarios, and I've run into an issue I need >>>some help with. I'm slowly eliminating EJB's from my application, but >>>I do have some legacy EJB code to deal with. In my scenario, my >>>servlet is calling a SLSB, which in turn calls spring-managed >>>transactional services. These transaction service join the CMT >>>transaction created by the EJB container. I have: >>> >>>Code: >>> >>>1) A servlet calls SLSB with CMT. >>>2) The SLSB calls SessionFactoryUtils.getSession(sessionFactory, true) >>>-- This binds the hibernate session to the current thread >>>3) The SLSB calls a spring-managed transactional service >>>-- This bean uses the bound session as expected >>>4) The SLSB calls another spring-managed transactional service >>>-- This bean uses the bound session as expected >>>5) The SLSB exits >>>-- The TransactionSynchronizationManager unbinds the bound session as >>>expected >>> >>> >>>So the non-timeout scenario functions as expected. Now I introduce a >>>timeout (by causing blocking in by database) prior to (3). With the >>>timeout scenario, I encounter one of two results: >>> >>>Code: >>> >>>A) A spring HibernateJdbcException wrapping a weblogic >>>TimedOutException as expected. >>>B) An IllegalStateException Already value >>>[org.springframework.orm.hibernate.SessionHolder@6f2304] for key >>>[net.sf.hibernate.impl.SessionFactoryImpl@655ad0] bound to thread >>>[ExecuteThread: '29' for queue: 'default'] >>> >>> >>>Whether I get (A) or (B) is seemingly random. I've created a >>>diagnostic version of SessionFactoryUtils to see what is happening in >>>more detail. >>>In scenario (B), it looks like WebLogic's transaction manager is >>>grabbing another thread from the pool and is invoking spring's >>>JtaSessionSynchronization.afterCompletion() which is resulting in >>>doClose() being called. I've added a dumpStack() in doClose(), and >>>here is what I see. The line numbers will be a little off because of >>>my diagnostic code: >>> >>>Code: >>> >>>java.lang.Exception: Stack trace >>> at java.lang.Thread.dumpStack(Thread.java:992) >>> at >>> >>> >>> >>> >>> >>org.springframework.orm.hibernate.SessionFactoryUtils.doClose(SessionFactor >> >> >y > > >>Utils.java:738) >> >> >> >> >>> at >>> >>> >>> >>> >>> >>org.springframework.orm.hibernate.SessionFactoryUtils.closeSessionOrRegiste >> >> >r > > >>DeferredClose(SessionFactoryUtils.java:726) >> >> >> >> >>> at >>> >>> >>> >>> >>> >>org.springframework.orm.hibernate.SessionFactoryUtils.access$300(SessionFac >> >> >t > > >>oryUtils.java:89) >> >> >> >> >>> at >>> >>> >>> >>> >>> >>org.springframework.orm.hibernate.SessionFactoryUtils$SpringSessionSynchron >> >> >i > > >>zation.beforeCompletion(SessionFactoryUtils.java:867) >> >> >> >> >>> at >>> >>> >>> >>> >>> >>org.springframework.orm.hibernate.SessionFactoryUtils$JtaSessionSynchroniza >> >> >t > > >>ion.afterCompletion(SessionFactoryUtils.java:978) >> >> >> >> >>> at >>> >>> >>> >>> >>> >>weblogic.transaction.internal.ServerSCInfo.callAfterCompletions(ServerSCInf >> >> >o > > >>.java:464) >> >> >> >> >>> at >>> >>> >>> >>> >>> >>weblogic.transaction.internal.ServerTransactionImpl.callAfterCompletions(Se >> >> >r > > >>verTransactionImpl.java:2139) >> >> >> >> >>> at >>> >>> >>> >>> >>> >>weblogic.transaction.internal.ServerTransactionImpl.setRolledBack(ServerTra >> >> >n > > >>sactionImpl.java:2090) >> >> >> >> >>> at >>> >>> >>> >>> >>> >>weblogic.transaction.internal.ServerTransactionImpl.globalRetryRollback(Ser >> >> >v > > >>erTransactionImpl.java:2188)DEBUG >> >> >> >> >>>18:19:23,000 [ExecuteThread: '34' for queue: 'default'] [edemo_acme] >>>(Transacti >>> at >>> >>> >>> >>> >>> >>weblogic.transaction.internal.ServerTransactionImpl.globalRollback(ServerTr >> >> >a > > >>nsactionImpl.java:2080) >> >> >> >> >>> at >>> >>> >>> >>> >>> >>weblogic.transaction.internal.TransactionImpl$1.execute(TransactionImpl.jav >> >> >a > > >>:1617) >> >> >> >> >>> at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:159) >>> at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:140) >>> >>> >>>Meanwhile, the original timeout thread, who is in the middle of >>>calling getSession(), and hasn't yet encountered the weblogic >>>TimedOutException, >>>tries to bind the session holder to the thread, and fails: >>> >>>Code: >>> >>>ERROR 18:19:23,046 [ExecuteThread: '34' for queue: 'default'] >>>[edemo_acme] (TransactionAspectSupport.java:264) - Application >>>exception overridden by rollback exception >>>java.lang.IllegalStateException: Already value >>>[org.springframework.orm.hibernate.SessionHolder@747db9] for key >>>[net.sf.hibernate.impl.SessionFactoryImpl@606e55] bound to thread >>>[ExecuteThread: '34' for queue: 'default'] >>> at >>> >>> >>> >>> >>> >>org.springframework.transaction.support.TransactionSynchronizationManager.b >> >> >i > > >>ndResource(TransactionSynchronizationManager.java:147) >> >> >> >> >>> at >>> >>> >>> >>> >>> >>org.springframework.orm.hibernate.SessionFactoryUtils.getSession(SessionFac >> >> >t > > >>oryUtils.java:346) >> >> >> >> >>> at >>> >>> >>> >>> >>> >>org.springframework.orm.hibernate.SessionFactoryUtils.getSession(SessionFac >> >> >t > > >>oryUtils.java:266) >> >> >> >> >>> at >>> >>> >>> >>> >>> >>org.springframework.orm.hibernate.SessionFactoryUtils.getSession(SessionFac >> >> >t > > >>oryUtils.java:223) >> >> >> >> >>> at >>> >>> >>> >>> >>> >>org.springframework.orm.hibernate.HibernateInterceptor.invoke(HibernateInte >> >> >r > > >>ceptor.java:149) >> >> >> >> >>> at >>> >>> >>> >>> >>> >>org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(Reflec >> >> >t > > >>iveMethodInvocation.java:144) >> >> >> >> >>> at >>> >>> >>> >>> >>> >>org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopPr >> >> >o > > >>xy.java:174) >> >> >> >> >>> at $Proxy93.findContract(Unknown Source) >>> at >>>mycode.ContractServiceImpl.findContract(ContractServiceImpl.java:59) >>> ... >>> >>> >>>It's not clear to me who the culprit is here, not being that familiar >>>with JTA and Spring. Perhaps the beforeCompletion() called by the >>>weblogic transaction manager is not cleaning up properly? Any ideas? >>> >>>Thanks for your help, >>>Dave >>> >>> >>>------------------------------------------------------- >>>This SF.Net email is sponsored by Oracle Space Sweepstakes >>>Want to be the first software developer in space? >>>Enter now for the Oracle Space Sweepstakes! >>>http://ads.osdn.com/?ad_id=7412&alloc_id=16344&op=click >>>_______________________________________________ >>>Springframework-developer mailing list >>>Spr...@li... >>>https://lists.sourceforge.net/lists/listinfo/springframework-developer >>> >>> >>> >>> >>> >>> >>------------------------------------------------------- >>This SF.Net email is sponsored by Oracle Space Sweepstakes >>Want to be the first software developer in space? >>Enter now for the Oracle Space Sweepstakes! >>http://ads.osdn.com/?ad_id=7412&alloc_id=16344&op=click >>_______________________________________________ >>Springframework-developer mailing list >>Spr...@li... >>https://lists.sourceforge.net/lists/listinfo/springframework-developer >> >> >> >>------------------------------------------------------- >>This SF.Net email is sponsored by Oracle Space Sweepstakes >>Want to be the first software developer in space? >>Enter now for the Oracle Space Sweepstakes! >>http://ads.osdn.com/?ad_id=7412&alloc_id=16344&op=click >>_______________________________________________ >>Springframework-developer mailing list >>Spr...@li... >>https://lists.sourceforge.net/lists/listinfo/springframework-developer >> >> >> >> >> >> > > >------------------------------------------------------- >This SF.Net email is sponsored by Oracle Space Sweepstakes >Want to be the first software developer in space? >Enter now for the Oracle Space Sweepstakes! >http://ads.osdn.com/?ad_id=7412&alloc_id=16344&op=click >_______________________________________________ >Springframework-developer mailing list >Spr...@li... >https://lists.sourceforge.net/lists/listinfo/springframework-developer > > > >------------------------------------------------------- >This SF.Net email is sponsored by Oracle Space Sweepstakes >Want to be the first software developer in space? >Enter now for the Oracle Space Sweepstakes! >http://ads.osdn.com/?ad_id=7412&alloc_id=16344&op=click >_______________________________________________ >Springframework-developer mailing list >Spr...@li... >https://lists.sourceforge.net/lists/listinfo/springframework-developer > > > > |