Hello,
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:
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: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
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.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' f or queue: 'default']
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:
Meanwhile, the original timeout thread, who is in the middle of calling getSession(), and hasn't yet encountered the weblogic TimedOutException,Code:java.lang.Exception: Stack trace at java.lang.Thread.dumpStack(Thread.java:992) at org.springframework.orm.hibernate.SessionFactoryUtils.doClose(SessionFactoryUtils.java:738) at org.springframework.orm.hibernate.SessionFactoryUtils.closeSessionOrRegisterDeferredClose(SessionFactoryUtils.java:726) at org.springframework.orm.hibernate.SessionFactoryUtils.access$300(SessionFactoryUtils.java:89) at org.springframework.orm.hibernate.SessionFactoryUtils$SpringSessionSynchronization.beforeCompletion(SessionFactoryUtils.java:867) at org.springframework.orm.hibernate.SessionFactoryUtils$JtaSessionSynchronization.afterCompletion(SessionFactoryUtils.java:978) at weblogic.transaction.internal.ServerSCInfo.callAfterCompletions(ServerSCInfo.java:464) at weblogic.transaction.internal.ServerTransactionImpl.callAfterCompletions(ServerTransactionImpl.java:2139) at weblogic.transaction.internal.ServerTransactionImpl.setRolledBack(ServerTransactionImpl.java:2090) at weblogic.transaction.internal.ServerTransactionImpl.globalRetryRollback(ServerTransactionImpl.java:2188)DEBUG 18:19:23,000 [ExecuteThread: '34' for queue: 'default'] [edemo_acme] (Transacti at weblogic.transaction.internal.ServerTransactionImpl.globalRollback(ServerTransactionImpl.java:2080) at weblogic.transaction.internal.TransactionImpl$1.execute(TransactionImpl.java:1617) at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:159) at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:140)
tries to bind the session holder to the thread, and fails:
It's not clear to me who the culprit is here, not being that familiar with JTA and Spring. Any ideas?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' f or queue: 'default'] at org.springframework.transaction.support.TransactionSynchronizationManager.bindResource(TransactionSynchronizationManager.java:147) at org.springframework.orm.hibernate.SessionFactoryUtils.getSession(SessionFactoryUtils.java:346) at org.springframework.orm.hibernate.SessionFactoryUtils.getSession(SessionFactoryUtils.java:266) at org.springframework.orm.hibernate.SessionFactoryUtils.getSession(SessionFactoryUtils.java:223) at org.springframework.orm.hibernate.HibernateInterceptor.invoke(HibernateInterceptor.java:149) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:174) at $Proxy93.findContract(Unknown Source) at mycode.ContractServiceImpl.findContract(ContractServiceImpl.java:59) ...
Thanks for your help,
Dave


Reply With Quote