Bug in Oracle XA connection pooling?
genman Sep 24, 2002 8:16 PM
I've been trying to isolate some problems I've been
having with transaction roll-backs and message-driven
beans. Basically, when a transaction is rolled-back
a number of times in the onMessage() body with
(by calling MessageDrivenContext.setRollbackOnly()),
the message is re-delivered to the MDB, but the Oracle
Connection is no longer in a good state.
This problem manifests itself when using a very small
connection pool (say 1-5) connections.
Example code snippet:
public void onMessage(javax.jms.Message jmsMessage)
{
Connection c = null;
try {
TextMessage tm = (TextMessage)jmsMessage;
String text = tm.getText();
c = ds.getConnection();
PreparedStatement s = c.prepareStatement("insert into test values (?)");
s.setString(1, text);
s.executeUpdate();
mdc.setRollbackOnly();
} catch (Exception e) {
throw new EJBException(e);
} finally {
if (c != null) {
try { c.close(); }
catch (Exception e) {
e.printStackTrace();
}
}
First I see it works for a few times. It rolls-back successfully
about 5 or 6 times. Then, for no reason, I see:
15:50:44,922 WARN [TxCapsule] XAException: tx=XidImpl [FormatId=257, GlobalId=eross.m-qube.com//4, BranchQual=] errorCode=XAER_RMERR
javax.transaction.xa.XAException
at oracle.jdbc.xa.OracleXAResource.allowGlobalTxnModeOnly(OracleXAResource.java:1069)
at oracle.jdbc.xa.OracleXAResource.suspendStacked(OracleXAResource.java:296)
at oracle.jdbc.xa.client.OracleXAResource.end(OracleXAResource.java:381)
at org.jboss.tm.TxCapsule.endResource(TxCapsule.java:1237)
at org.jboss.tm.TxCapsule.delistResource(TxCapsule.java:579)
at org.jboss.tm.TransactionImpl.delistResource(TransactionImpl.java:92)
at org.jboss.resource.connectionmanager.XATxConnectionManager$XAConnectionEventListener.delist(XATxConnectionManager.java:284)
at org.jboss.resource.connectionmanager.XATxConnectionManager$XAConnectionEventListener.connectionClosed(XATxConnectionManager.java:331)
at org.jboss.resource.adapter.jdbc.BaseManagedConnection.fireConnectionEvent(BaseManagedConnection.java:152)
at org.jboss.resource.adapter.jdbc.xa.XAManagedConnection.fireConnectionEvent(XAManagedConnection.java:215)
at org.jboss.resource.adapter.jdbc.xa.XAManagedConnection$1.connectionClosed(XAManagedConnection.java:127)
at oracle.jdbc.pool.OraclePooledConnection.callListener(OraclePooledConnection.java:482)
at oracle.jdbc.pool.OraclePooledConnection.logicalClose(OraclePooledConnection.java:445)
at oracle.jdbc.driver.OracleConnection.logicalClose(OracleConnection.java:2900)
at oracle.jdbc.driver.OracleConnection.close(OracleConnection.java:1418)
at com.proteusmobile.smx.AMDB.onMessage(AMDB.java:140)
Later:
15:50:44,929 WARN [TxCapsule] XAException: tx=XidImpl [FormatId=257, GlobalId=eross.m-qube.com//4, BranchQual=] errorCode=XAER_RMERR
javax.transaction.xa.XAException
at oracle.jdbc.xa.OracleXAResource.allowGlobalTxnModeOnly(OracleXAResource.java:1069)
at oracle.jdbc.xa.OracleXAResource.suspendStacked(OracleXAResource.java:296)
at oracle.jdbc.xa.client.OracleXAResource.end(OracleXAResource.java:381)
at org.jboss.tm.TxCapsule.endResource(TxCapsule.java:1237)
at org.jboss.tm.TxCapsule.endResources(TxCapsule.java:1312)
at org.jboss.tm.TxCapsule.rollback(TxCapsule.java:440)
at org.jboss.tm.TransactionImpl.rollback(TransactionImpl.java:83)
at org.jboss.jms.asf.StdServerSession.onMessage(StdServerSession.java:301)
at org.jboss.mq.SpyMessageConsumer.sessionConsumerProcessMessage(SpyMessageConsumer.java:603)
at org.jboss.mq.SpyMessageConsumer.addMessage(SpyMessageConsumer.java:417)
at org.jboss.mq.SpySession.run(SpySession.java:259)
at org.jboss.jms.asf.StdServerSession.run(StdServerSession.java:177)
at EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor.java:655)
at java.lang.Thread.run(Thread.java:479)
And then, I can no longer get a connection:
15:50:44,971 WARN [TxCapsule] XAException: tx=XidImpl [FormatId=257, GlobalId=eross.m-qube.com//5, BranchQual=] errorCode=XAER_PROTO
javax.transaction.xa.XAException
at oracle.jdbc.xa.OracleXAResource.disallowLocalTxnMode(OracleXAResource.java:1045)
at oracle.jdbc.xa.client.OracleXAResource.start(OracleXAResource.java:153)
at org.jboss.tm.TxCapsule.startResource(TxCapsule.java:1180)
at org.jboss.tm.TxCapsule.enlistResource(TxCapsule.java:679)
at org.jboss.tm.TransactionImpl.enlistResource(TransactionImpl.java:102)
at org.jboss.resource.connectionmanager.XATxConnectionManager$XAConnectionEventListener.enlist(XATxConnectionManager.java:262)
at org.jboss.resource.connectionmanager.XATxConnectionManager.managedConnectionReconnected(XATxConnectionManager.java:202)
at org.jboss.resource.connectionmanager.BaseConnectionManager2.allocateConnection(BaseConnectionManager2.java:534)
at org.jboss.resource.connectionmanager.BaseConnectionManager2$ConnectionManagerProxy.allocateConnection(BaseConnectionManager2.java:812)
at org.jboss.resource.adapter.jdbc.JDBCDataSource.getConnection(JDBCDataSource.java:110)
at com.proteusmobile.smx.AMDB.onMessage(AMDB.java:91)
In oracle.jdbc.xa.OracleXAResource (decompiled snippets):
protected void allowGlobalTxnModeOnly(int i)
throws XAException
{
if(((OracleConnection)m_conn).m_txn_mode != 2)
throw new XAException(i);
else
return;
}
//...
protected void disallowLocalTxnMode(int i)
throws XAException
{
if(((OracleConnection)m_conn).m_txn_mode == 1)
throw new XAException(i);
else
return;
}
I can no longer get a connection at all, as the
DataSource.getConnection() will no longer work.
I assume it's due to some funky state changes that have
come along with the repeated roll-backs.