Our application uses SLSBs which act as a thin facade layer that call directly into Spring POJO services. The session beans all have a transaction attribute of Supports. All of these service classes have been proxied, using the MatchAlwaysTransactionAttributeSource interceptor to ensure that each service call will be within a transaction. All data access occurs within the services.
In addition, we have a transaction filter in our web front-end which starts the transaction and keeps it open for the life of the request. Reason for this is eventually, our front-end will call our Spring services directly, instead of the SLSBs. That way, multiple service calls in the front end can participate in the same transaction. Unfortunately, not all of our front end code has been updated to call the services, some still do call the SLSBs.
What happens on Weblogic is, if I call a method on a SLSB and an error occurs, the transaction is marked for rollback (which is all good). But then, in some cases, the front end makes other calls to the back end to retrieve certain data so an error page can be displayed. These extra calls after the rollback fail, getting an error such as:
I also tried changing the transaction attribute on the Session Beans to RequiresNew, thinking that way once the facade is called, the transaction started at the beginning of the request would be suspended, and all calls from within the SLSB would be part of a new transaction. What happens is this:2005-06-16 09:19:46,675 [ExecuteThread: '13' for queue: 'weblogic.kernel.Default'] ERROR rome.business.service.RatingServiceImpl - (User:administrator) Transaction BEA1-01DA1B88B7917F28EDB9 not active anymore. tx status = Marked rollback. [Reason=weblogic.transaction.internal.AppSetRollbac kOnlyException]
java.sql.SQLException: Transaction BEA1-01DA1B88B7917F28EDB9 not active anymore. tx status = Marked rollback. [Reason=weblogic.transaction.internal.AppSetRollbac kOnlyException]
at weblogic.jdbc.jts.Driver.getTransaction(Driver.jav a:367)
at weblogic.jdbc.common.internal.RmiDataSource.getCon nection(RmiDataSource.java:305)
And this happens on successful calls. It appears the second SLSB call in the front-end class is trying to use the same transaction, instead of a new one that I would think RequiresNew implies.org.springframework.jdbc.UncategorizedSQLException : (Hibernate operation): encountered SQLException [The transaction is no longer active - status: 'Committed'. No further JDBC access is allowed within this transaction.]; nested exception is java.sql.SQLException: The transaction is no longer active - status: 'Committed'. No further JDBC access is allowed within this transaction.
java.sql.SQLException: The transaction is no longer active - status: 'Committed'. No further JDBC access is allowed within this transaction.
at weblogic.jdbc.wrapper.JTSConnection.checkIfRolledB ack(JTSConnection.java:118)
at weblogic.jdbc.wrapper.JTSConnection.checkConnectio n(JTSConnection.java:127)
at weblogic.jdbc.wrapper.Connection.prepareStatement( Connection.java:324)
at weblogic.jdbc.wrapper.JTSConnection.prepareStateme nt(JTSConnection.java:426)
at net.sf.hibernate.impl.BatcherImpl.getPreparedState ment(BatcherImpl.java:263)
I have seen comments on the web that this is somewhat of a known Weblogic issue, where once a transaction is marked for rollback, weblogic will not resume the transaction, and that we should use org.springframework.transaction.jta.WebLogicJtaTra nsactionManager as our JTA Transaction Manager. I declared that in our application context, but seems to do no good.
Any ideas? BTW, all of this works beautifully on JBoss. Seems to be just weblogic which is fussy.