Could you please help to solve the problem with XA transactions on Resin + Oracle:
We have WebApp which has to execute business transactions which involve both Oracle 11.2.0.1 and Ehcache 2.7. (Actually various combinations possible – two different Oracle data sources (different schemas) with/without Ehcache, etc). This was the reason to switch from plain JDBC usage to JTA transactions demarcation.
We use: - Resin JTA implementation which is decorated with Spring 3.2.1 to simplify transactions suspending and make use of programmatic approach to transaction boundaries definition (“manual” usage of TransactionManager for suspending/resuming also gives a problem) as follows:
public void doOuterTransaction() throws Throwable {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName("myTx");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES);
TransactionStatus status = txManager.getTransaction(def);
Connection connection = null;
Cache cache = null;
try {
cache = ...; // get cache from CacheManager
connection = myDataSource.getConnection(); // or "DataSourceUtils.getConnection(myDataSource)" to guarantee same dbConnection from Spring
// some business logic
doInnerTransaction();
// some business logic
txManager.commit(status);
} catch (Throwable ex) {
txManager.rollback(status);
throw ex;
} finally {
if (connection!=null) {
connection.close();
}
}
}
public void doInnerTransaction() throws Throwable {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName("myTx");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus status = txManager.getTransaction(def);
Connection connection = null;
Cache cache = null;
try {
cache = ...; // get cache from CacheManager
connection = myDataSource.getConnection(); // or "DataSourceUtils.getConnection(myDataSource)" to guarantee same dbConnection from Spring
// some business logic
txManager.commit(status);
} catch (Throwable ex) {
txManager.rollback(status);
throw ex;
} finally {
if (connection!=null) {
connection.close();
}
}
}
- Ehcache with caches configured with “XA” transactions support.
Resin connections pool with Oracle driver “oracle.jdbc.xa.client.OracleXADataSource”, configured via resin.conf as follows
<database> <name>my_xa_datasource</name> <jndi-name>jdbc/my_xa</jndi-name> <driver> <type>oracle.jdbc.xa.client.OracleXADataSource</type> <url>${MY_DB_URL}</url> <user>${MY_DB_USERNAME}</user> <password>${MY_DB_PASSWORD}</password> </driver> <max-connections>50</max-connections> <max-idle-time>60s</max-idle-time> <max-active-time>24h</max-active-time> <max-overflow-connections>15</max-overflow-connections> <ping>true</ping> <ping-table>DUAL</ping-table> <ping-interval>240s</ping-interval> <transaction-timeout>24h</transaction-timeout> <xa>true</xa> </database>
All transactions with any combination of affected resources with propagation level REQUIRED works fine out of the box. But when we have the case with outer transaction “REQUIRED” and inner transaction “REQUIRES_NEW” – suspending outer transaction causes problems and inner transaction couldn't be committed. And even more - already running inner transaction we can see UNcommited changes from outer transaction which looks completely wrong.
Behavior depends on which resources are involved in outer and inner transactions. We have following cases: 1. Having only Ehcache access in both inner and outer transactions works fine even with REQUIRES_NEW for inner one.
Having Ehcache access in outer transaction and DB access ONLY in inner transaction also works fine even with REQUIRES_NEW for inner one.
Case with DB access in outer transaction or in both transactions (NO matter how many DataSources are involved, even if DataSources usage does not overlaps transaction boundaries) gives the following error with commit of inner transaction:
_
ch.sc.common.ShortAGRuntimeException: org.springframework.transaction.TransactionSystemException:
JTA failure on commit; nested exception is com.caucho.transaction.SystemExceptionWrapper:
XA_RMERR: Resource manager error.
at ch.sc.glibs.mytest.MyTestServlet.doGet(MyTestServlet.java:34)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:120)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:97)
at com.caucho.server.dispatch.ServletFilterChain.doFilter(ServletFilterChain.java:109)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at com.caucho.server.security.SecurityFilterChain.doFilter(SecurityFilterChain.java:132)
at com.caucho.server.webapp.WebAppListenerFilterChain.doFilter(WebAppListenerFilterChain.java:114)
at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:156)
at com.caucho.server.webapp.AccessLogFilterChain.doFilter(AccessLogFilterChain.java:95)
at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:289)
at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:838)
at com.caucho.network.listen.TcpSocketLink.dispatchRequest(TcpSocketLink.java:1309)
at com.caucho.network.listen.TcpSocketLink.handleRequest(TcpSocketLink.java:1265)
at com.caucho.network.listen.TcpSocketLink.handleRequestsImpl(TcpSocketLink.java:1249)
at com.caucho.network.listen.TcpSocketLink.handleRequests(TcpSocketLink.java:1157)
at com.caucho.network.listen.TcpSocketLink.handleAcceptTaskImpl(TcpSocketLink.java:956)
at com.caucho.network.listen.ConnectionTask.runThread(ConnectionTask.java:117)
at com.caucho.network.listen.ConnectionTask.run(ConnectionTask.java:93)
at com.caucho.network.listen.SocketLinkThreadLauncher.handleTasks(SocketLinkThreadLauncher.java:169)
at com.caucho.network.listen.TcpSocketAcceptThread.run(TcpSocketAcceptThread.java:61)
at com.caucho.env.thread2.ResinThread2.runTasks(ResinThread2.java:173)
at com.caucho.env.thread2.ResinThread2.run(ResinThread2.java:118)
Caused by: org.springframework.transaction.TransactionSystemException:
JTA failure on commit; nested exception is com.caucho.transaction.SystemExceptionWrapper:
XA_RMERR: Resource manager error.
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1025)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at ch.sc.glibs.mytest.MyTxTest.test3(MyTxTest.java:155)
at ch.sc.glibs.mytest.MyTxTest.doMainComplexTx(MyTxTest.java:81)
at ch.sc.glibs.mytest.MyTxTest.doTxTest(MyTxTest.java:50)
at ch.sc.glibs.mytest.MyTxTest__ResinScopeProxy.doTxTest(Unknown Source)
at ch.sc.glibs.mytest.MyTestServlet.doGet(MyTestServlet.java:32)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:120)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:97)
at com.caucho.server.dispatch.ServletFilterChain.doFilter(ServletFilterChain.java:109)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at com.caucho.server.security.SecurityFilterChain.doFilter(SecurityFilterChain.java:132)
at com.caucho.server.webapp.WebAppListenerFilterChain.doFilter(WebAppListenerFilterChain.java:114)
at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:156)
at com.caucho.server.webapp.AccessLogFilterChain.doFilter(AccessLogFilterChain.java:95)
at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:289)
at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:838)
at com.caucho.network.listen.TcpSocketLink.dispatchRequest(TcpSocketLink.java:1309)
at com.caucho.network.listen.TcpSocketLink.handleRequest(TcpSocketLink.java:1265)
at com.caucho.network.listen.TcpSocketLink.handleRequestsImpl(TcpSocketLink.java:1249)
at com.caucho.network.listen.TcpSocketLink.handleRequests(TcpSocketLink.java:1157)
at com.caucho.network.listen.TcpSocketLink.handleAcceptTaskImpl(TcpSocketLink.java:956)
at com.caucho.network.listen.ConnectionTask.runThread(ConnectionTask.java:117)
at com.caucho.network.listen.ConnectionTask.run(ConnectionTask.java:93)
at com.caucho.network.listen.SocketLinkThreadLauncher.handleTasks(SocketLinkThreadLauncher.java:169)
at com.caucho.network.listen.TcpSocketAcceptThread.run(TcpSocketAcceptThread.java:61)
at com.caucho.env.thread2.ResinThread2.runTasks(ResinThread2.java:173)
at com.caucho.env.thread2.ResinThread2.run(ResinThread2.java:118)
Caused by: com.caucho.transaction.SystemExceptionWrapper: XA_RMERR: Resource
manager error.
at com.caucho.transaction.TransactionImpl.heuristicException(TransactionImpl.java:1040)
at com.caucho.transaction.TransactionImpl.commitResources(TransactionImpl.java:931)
at com.caucho.transaction.TransactionImpl.commit(TransactionImpl.java:886)
at com.caucho.transaction.TransactionManagerImpl.commit(TransactionManagerImpl.java:324)
at com.caucho.transaction.UserTransactionImpl.commit(UserTransactionImpl.java:363)
at com.caucho.transaction.UserTransactionProxy.commit(UserTransactionProxy.java:171)
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1009)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at ch.sc.glibs.mytest.MyTxTest.test3(MyTxTest.java:155)
at ch.sc.glibs.mytest.MyTxTest.doMainComplexTx(MyTxTest.java:81)
at ch.sc.glibs.mytest.MyTxTest.doTxTest(MyTxTest.java:50)
at ch.sc.glibs.mytest.MyTxTest__ResinScopeProxy.doTxTest(Unknown Source)
at ch.sc.glibs.mytest.MyTestServlet.doGet(MyTestServlet.java:32)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:120)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:97)
at com.caucho.server.dispatch.ServletFilterChain.doFilter(ServletFilterChain.java:109)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at com.caucho.server.security.SecurityFilterChain.doFilter(SecurityFilterChain.java:132)
at com.caucho.server.webapp.WebAppListenerFilterChain.doFilter(WebAppListenerFilterChain.java:114)
at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:156)
at com.caucho.server.webapp.AccessLogFilterChain.doFilter(AccessLogFilterChain.java:95)
at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:289)
at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:838)
at com.caucho.network.listen.TcpSocketLink.dispatchRequest(TcpSocketLink.java:1309)
at com.caucho.network.listen.TcpSocketLink.handleRequest(TcpSocketLink.java:1265)
at com.caucho.network.listen.TcpSocketLink.handleRequestsImpl(TcpSocketLink.java:1249)
at com.caucho.network.listen.TcpSocketLink.handleRequests(TcpSocketLink.java:1157)
at com.caucho.network.listen.TcpSocketLink.handleAcceptTaskImpl(TcpSocketLink.java:956)
at com.caucho.network.listen.ConnectionTask.runThread(ConnectionTask.java:117)
at com.caucho.network.listen.ConnectionTask.run(ConnectionTask.java:93)
at com.caucho.network.listen.SocketLinkThreadLauncher.handleTasks(SocketLinkThreadLauncher.java:169)
at com.caucho.network.listen.TcpSocketAcceptThread.run(TcpSocketAcceptThread.java:61)
at com.caucho.env.thread2.ResinThread2.runTasks(ResinThread2.java:173)
at com.caucho.env.thread2.ResinThread2.run(ResinThread2.java:118)
Caused by: oracle.jdbc.xa.OracleXAException
at oracle.jdbc.xa.OracleXAResource.checkError(OracleXAResource.java:1110)
at oracle.jdbc.xa.client.OracleXAResource.end(OracleXAResource.java:436)
at com.caucho.sql.DisjointXAResource.end(DisjointXAResource.java:105)
at com.caucho.env.dbpool.ManagedPoolItem.endResource(ManagedPoolItem.java:1017)
at com.caucho.env.dbpool.ManagedPoolItem.commit(ManagedPoolItem.java:957)
at com.caucho.transaction.TransactionImpl.commitResources(TransactionImpl.java:924)
at com.caucho.transaction.TransactionImpl.commit(TransactionImpl.java:886)
at com.caucho.transaction.TransactionManagerImpl.commit(TransactionManagerImpl.java:324)
at com.caucho.transaction.UserTransactionImpl.commit(UserTransactionImpl.java:363)
at com.caucho.transaction.UserTransactionProxy.commit(UserTransactionProxy.java:171)
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1009)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at ch.sc.glibs.mytest.MyTxTest.test3(MyTxTest.java:155)
at ch.sc.glibs.mytest.MyTxTest.doMainComplexTx(MyTxTest.java:81)
at ch.sc.glibs.mytest.MyTxTest.doTxTest(MyTxTest.java:50)
at ch.sc.glibs.mytest.MyTxTest__ResinScopeProxy.doTxTest(Unknown Source)
at ch.sc.glibs.mytest.MyTestServlet.doGet(MyTestServlet.java:32)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:120)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:97)
at com.caucho.server.dispatch.ServletFilterChain.doFilter(ServletFilterChain.java:109)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at ch.sc.common.http.filters.RegexpFilteringProxyFilter.doFilter(RegexpFilteringProxyFilter.java:65)
at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:89)
at com.caucho.server.security.SecurityFilterChain.doFilter(SecurityFilterChain.java:132)
at com.caucho.server.webapp.WebAppListenerFilterChain.doFilter(WebAppListenerFilterChain.java:114)
at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:156)
at com.caucho.server.webapp.AccessLogFilterChain.doFilter(AccessLogFilterChain.java:95)
at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:289)
at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:838)
at com.caucho.network.listen.TcpSocketLink.dispatchRequest(TcpSocketLink.java:1309)
at com.caucho.network.listen.TcpSocketLink.handleRequest(TcpSocketLink.java:1265)
at com.caucho.network.listen.TcpSocketLink.handleRequestsImpl(TcpSocketLink.java:1249)
at com.caucho.network.listen.TcpSocketLink.handleRequests(TcpSocketLink.java:1157)
at com.caucho.network.listen.TcpSocketLink.handleAcceptTaskImpl(TcpSocketLink.java:956)
at com.caucho.network.listen.ConnectionTask.runThread(ConnectionTask.java:117)
at com.caucho.network.listen.ConnectionTask.run(ConnectionTask.java:93)
at com.caucho.network.listen.SocketLinkThreadLauncher.handleTasks(SocketLinkThreadLauncher.java:169)
at com.caucho.network.listen.TcpSocketAcceptThread.run(TcpSocketAcceptThread.java:61)
at com.caucho.env.thread2.ResinThread2.runTasks(ResinThread2.java:173)
at com.caucho.env.thread2.ResinThread2.run(ResinThread2.java:118)
Internally we see ORA-25352 “no current transaction” “The user session is not attached to any transaction” during prepare commit phase (call to Oracle JAVA_XA.prepare returns an error code). It looks as if during inner transaction commit application for some reason involves resources (DataSource) affected in outer transaction which seems to be incorrect because with no db usage in inner transaction we expect no call to Oracle.
The worst thing is that using Apache DBCP pool instead of Resin pool implementation SOLVES the problem… Usage of Atomikos (both TransactionManager implementation and Connections Pool implementation) also works fine. But both mentioned implementations have their own problem.
At the moment we suppose that we are having problem with DB pool or XA driver configuration… Could the problem be linked with any enhancements like using local transactions instead of global, etc? We tried various resources definition (database, resource-ref), used “xa-forbid-same-rm”, switched off spring transaction synchronization, tried to use TransactionManager manually to suspend/resume transaction, etc - everything with no luck.
Any ideas/solutions are welcome!