bug in BaseWrapperManagedConnection?
nlmarco May 3, 2008 10:01 AMHello *,
I've stumbled over a problem when switching to XA transactions: I got quite often exceptions like these:
452592 ERROR (francois@chezfrancois.jfire.org) [Persist] Update of object "org.nightlabs.jfire.trade.Offer@1ac1a3c" using statement "UPDATE `JFIRETRADE_OFFER` SET `STATE_ORGANISATION_ID_OID`=?, `STATE_STATE_ID_OID`=?, `OPT_VERSION`=? WHERE `OFFER_ID`=? AND `OFFER_IDPREFIX`=? AND `ORGANISATION_ID`=?" failed : java.sql.SQLException: Can't set autocommit to 'true' on an XAConnection
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:946)
at com.mysql.jdbc.jdbc2.optional.ConnectionWrapper.setAutoCommit(ConnectionWrapper.java:103)
at org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection.checkTransaction(BaseWrapperManagedConnection.java:429)
at org.jboss.resource.adapter.jdbc.WrappedConnection.checkTransaction(WrappedConnection.java:525)
at org.jboss.resource.adapter.jdbc.WrappedConnection.prepareStatement(WrappedConnection.java:184)
at org.datanucleus.store.rdbms.SQLController.getStatementForUpdate(SQLController.java:229)
at org.datanucleus.store.rdbms.request.UpdateRequest.execute(UpdateRequest.java:229)
at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.updateTable(RDBMSPersistenceHandler.java:336)
at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.updateObject(RDBMSPersistenceHandler.java:312)
at org.datanucleus.state.JDOStateManagerImpl.flush(JDOStateManagerImpl.java:4610)
at org.datanucleus.ObjectManagerImpl.flushInternal(ObjectManagerImpl.java:2707)
at org.datanucleus.ObjectManagerImpl.flush(ObjectManagerImpl.java:2647)
at org.datanucleus.jdo.AbstractPersistenceManager.flush(AbstractPersistenceManager.java:1956)
at org.datanucleus.jdo.connector.ConnectionXAResource.end(ConnectionXAResource.java:78)
at org.jboss.resource.connectionmanager.xa.JcaXAResourceWrapper.end(JcaXAResourceWrapper.java:58)
at com.arjuna.ats.internal.jta.resources.arjunacore.XAResourceRecord.topLevelPrepare(XAResourceRecord.java:259)
at com.arjuna.ats.arjuna.coordinator.BasicAction.doPrepare(BasicAction.java:2871)
at com.arjuna.ats.arjuna.coordinator.BasicAction.doPrepare(BasicAction.java:2828)
at com.arjuna.ats.arjuna.coordinator.BasicAction.prepare(BasicAction.java:2382)
at com.arjuna.ats.arjuna.coordinator.BasicAction.End(BasicAction.java:1783)
at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:90)
at com.arjuna.ats.arjuna.AtomicAction.end(AtomicAction.java:216)
at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commit(TransactionImple.java:228)
at org.jboss.ejb.plugins.TxInterceptorCMT.endTransaction(TxInterceptorCMT.java:501)
at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:361)
at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:181)
at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:168)
at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:205)
at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:138)
at org.jboss.ejb.SessionContainer.internalInvoke(SessionContainer.java:648)
at org.jboss.ejb.Container.invoke(Container.java:960)
at sun.reflect.GeneratedMethodAccessor118.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.invocation.unified.server.UnifiedInvoker.invoke(UnifiedInvoker.java:231)
at sun.reflect.GeneratedMethodAccessor148.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at javax.management.MBeanServerInvocationHandler.invoke(MBeanServerInvocationHandler.java:288)
at $Proxy16.invoke(Unknown Source)
at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:734)
at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:560)
at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:383)
at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:165)
I first thought, it was a bug in DataNucleus, but since DataNucleus works fine in other JavaEE servers, I digged deeper into it and took a look into the sources of JBoss 4.2.0. I saw that the method org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection#checkTransaction() accesses the field jdbcAutoCommit directly:
if (jdbcAutoCommit != underlyingAutoCommit) { con.setAutoCommit(jdbcAutoCommit); underlyingAutoCommit = jdbcAutoCommit; }
...even though there is a getter for it, which takes the field inManagedTransaction into account:
boolean isJdbcAutoCommit() { return inManagedTransaction? false: jdbcAutoCommit; }
Together with the code in the method cleanup(), which sets jdbcAutoCommit to true, this is IMHO responsible for my problem.
I downloaded JBoss 4.2.2 and tried it again - the bug still exists in the newest stable version, as well.
Am I right, is that a bug in this class? Could you please fix it?
Best regards, Marco :-)