-->
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.  [ 1 post ] 
Author Message
 Post subject: ThreadLocal and CMT rollback issues - can't close connection
PostPosted: Wed Jun 23, 2004 2:35 am 
Newbie

Joined: Wed Dec 10, 2003 8:40 pm
Posts: 9
Hi there,
I am having some issues with CMT rollbacks not working correctly.

I am using the Steve Ebersole variation on the ThreadLocal pattern, and stateless session beans calling DAOs for data access. On Weblogic 8.1, sql server 7. I find that when I use a new Session per operation all CMT rollbacks seem to work fine. The below code shows a dao save method, which is called from a SLSB method (also shown below) - the session is opened and closed around the save call. The rollback works correctly in this case.


public void save(Object entity) throws DataAccessException {

try {
Session session = HibernateSession.currentSession();
session.save(entity);
session.flush();
}
catch (HibernateException he) {
throw new DataAccessException("error ocurred executing save call ", he);
}
finally {
HibernateSession.closeSession();
}
}

/**
* @ejb.business-method
* @ejb.interface-method
* @ejb.transaction type="Required"
*/
public void insertExample() {

try{


CreditCardPaymentHDO hdo = new CreditCardPaymentHDO();
HibernateDaoSupport dao = new HibernateDaoSupport();

dao.save( hdo);
throw new NullPointerException("will have to rollback now");

}catch(Throwable t){
getSessionContext().setRollbackOnly();
}
}


However I would like open the session at the start of a SLSB method, do a number of loads, saves etc and close the session at the end of the SLSB method to take advantage of lazy loads, session caching etc (all in the same CMT transaction). However I find that the following EJB code results in weblogic throwing an exception when the closeSession() method is called from the finally clause.


/**
* @ejb.business-method
* @ejb.interface-method
* @ejb.transaction type="Required"
*/
public void insertExample() {

try{
HibernateSession.currentSession();

CreditCardPaymentHDO hdo = new CreditCardPaymentHDO();
HibernateDaoSupport dao = new HibernateDaoSupport();

dao.save( hdo);
throw new NullPointerException("will have to rollback now");

}catch(Throwable t){
getSessionContext().setRollbackOnly();
}finally{
HibernateSession.closeSession();
}
}



javax.ejb.EJBException: EJB Exception: : au.com.wanews.olps.framework.exception.DataAccessException: Error closing hibernate session
at au.com.wanews.olps.framework.database.hibernate.HibernateSession.closeSession(HibernateSession.java:78)
at au.com.wanews.olps.beans.advertisementlodgement.AdvertisementLodgementEJB.retrieveReferenceTables(AdvertisementLodgementEJB.java:543)
at au.com.wanews.olps.beans.advertisementlodgement.AdvertisementLodgementEJB_mkl5ls_ELOImpl.retrieveReferenceTables(AdvertisementLodgementEJB_mkl5ls_ELOImpl.java:325)
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:324)
at org.springframework.ejb.access.LocalSlsbInvokerInterceptor.invoke(LocalSlsbInvokerInterceptor.java:41)
at org.springframework.aop.framework.MethodInvocationImpl.proceed(MethodInvocationImpl.java:216)
at org.springframework.aop.framework.AopProxy.invoke(AopProxy.java:137)
at $Proxy20.retrieveReferenceTables(Unknown Source)
at au.com.wanews.olps.website.tests.EjbTestServlet.test0(EjbTestServlet.java:249)
at au.com.wanews.olps.website.tests.EjbTestServlet.doGet(EjbTestServlet.java:233)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:1053)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:387)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:28)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:27)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:6316)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:317)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:118)
at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:3622)
at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2569)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:197)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:170)
Caused by: net.sf.hibernate.JDBCException: Cannot close connection
at net.sf.hibernate.impl.BatcherImpl.closeConnection(BatcherImpl.java:273)
at net.sf.hibernate.impl.SessionImpl.disconnect(SessionImpl.java:3203)
at net.sf.hibernate.impl.SessionImpl.close(SessionImpl.java:549)
at au.com.wanews.olps.framework.database.hibernate.HibernateSession.closeSession(HibernateSession.java:75)
... 25 more
Caused by: java.sql.SQLException: The transaction is no longer active - status: 'Marked rollback. [Reason=weblogic.transaction.internal.AppSetRollbackOnlyException]'. No further JDBC access is allowed within this transaction.
at weblogic.jdbc.wrapper.JTSConnection.checkIfRolledBack(JTSConnection.java:118)
at weblogic.jdbc.wrapper.JTSConnection.checkConnection(JTSConnection.java:127)
at weblogic.jdbc.wrapper.Connection.preInvocationHandler(Connection.java:67)
at weblogic.jdbc.wrapper.JTSConnection_weblogic_jdbc_sqlserver_SQLServerConnection.getWarnings(Unknown Source)
at net.sf.hibernate.impl.BatcherImpl.closeConnection(BatcherImpl.java:267)
... 28 more
; nested exception is: au.com.wanews.olps.framework.exception.DataAccessException: Error closing hibernate session



It looks like weblogic expects that the connection should be closed prior to calling getSessionContext().setRollbackOnly(). I guess that the session per operation works correctly because the session is closed prior to calling setRollbackOnly(). Can anyone suggest why this might be so ? I would really like to execute the whole ejb method using the one Session. Interestingly, if I don't catch the Throwable but let the container rollback the transaction all is fine (no exceptions thrown and changes rolled back).

Any help on this greatly appreciated.

Tom.




[/b]


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

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.