Bugs item #614116, was opened at 2002-09-24 16:56
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=376685&aid=614116&group_id=22866

Category: JBossTX
Group: v3.0 Rabbit Hole
Status: Open
Resolution: None
Priority: 5
Submitted By: Elias Ross (genman)
Assigned to: Nobody/Anonymous (nobody)
Summary: Oracle XA pooling/repeated rollback

Initial Comment:

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
(by calling MessageDrivenContext.setRollbackOnly()
5-10 times in succession),
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.
 



----------------------------------------------------------------------

>Comment By: Elias Ross (genman)
Date: 2002-10-01 20:51

Message:
Logged In: YES 
user_id=556458

>From what I have seen in the bug database, Oracle hasn't
had a very good track record.

Thanks for taking a good look at this, and I'll let my team
know about this problem.  In the meantime, I'll wait with
bated breath for version 3.2.



----------------------------------------------------------------------

Comment By: Igor Fedorenko (igorfie)
Date: 2002-10-01 18:57

Message:
Logged In: YES 
user_id=232950

I took a closer look on this problem and think that I know 
what is going on.  Basically, we have two transactions 
TX1 and TX2 both using same xa connection and 
executed concurrently on two different threads

tx1: start jms 
tx1: start oracle
tx1:   get connection
tx1:   prepare statement
tx1:   execute update
tx1: end oracle
tx1: rollback jms  =>   tx2: start jms
                                       tx2: start oracle
                                       tx2: get connection
tx1: rollback oracle **  tx2: prepare statement **

** this is when first exception is thrown. note that 
sometimes second transaction gets enough time to 
execute update.

I am not sure if you can see the table above ;-) but the 
idea is that when jms session rolls back jms message is 
redelivered and cunsumed in a new transaction that 
works in parallel with original tx. Notice that TX2 
executes prepareStatement at the same time TX1 calls 
rollback on oracle xa resource. And this is where oracle 
does not shine and all :-(

I wrote few tests to exercise this scenario and ran them 
with oracle 8173 and jdbc drivers version 9201. These 
tests showed that oracle xa drivers are not thread safe. 

There are few possible options to fix this problem. First, 
it is possible that problem will disappear with oracle 
9201 and introduction of minor sinchronization between 
calls to shared xa connection. Second, we could 
configure JBOSS not to use same xa resource in two 
concurrent transactions (this option is available in JBOSS 
3.2 and 4.0). Third, we could introduce heavy 
synchronization of xa connection calls; I did some 
prototyping here and it looks like we need to 
synchronize all calls to xa connection and its derived 
objects (xa resource, connection, statements and result 
sets). I consider last option as a very last resort and 
would not try to implement until all other possibilities are 
eliminated.

PS: if somebody wants to take a look on my tests (or/and 
discuss them with oracle?) I'll be glad to make them 
available.
PSS: I still hope to get oracle 9i later this week.

----------------------------------------------------------------------

Comment By: Elias Ross (genman)
Date: 2002-09-26 10:11

Message:
Logged In: YES 
user_id=556458


Yes it is version 9201 on Linux.

Perhaps the problem has resolved itself in a later version of 
JBoss?

I appreciate you looking into this.

----------------------------------------------------------------------

Comment By: Igor Fedorenko (igorfie)
Date: 2002-09-25 11:59

Message:
Logged In: YES 
user_id=232950

I'll try to reproduce this problem when I get oracle 9201 
around (which is expected to happen next week but I do not 
have control over it). Am I right in an assumption that your 
server version is 9201?

----------------------------------------------------------------------

Comment By: Elias Ross (genman)
Date: 2002-09-25 11:08

Message:
Logged In: YES 
user_id=556458


Jboss is version 3.0.1 -- using Oracle 9.2.0.1 thin
drivers.  (Specifically jboss-3.0.1_tomcat-4.0.4).

Also, when the connection is being removed from the connection
pool, I see:

15:54:45,197 INFO  [JBossManagedConnectionPool] Exception destroying ManagedConnection
javax.resource.ResourceException: Unable to close DB connection: 
java.sql.SQLException: ORA-02089: COMMIT is 
not allowed in a subordinate session
        at 
org.jboss.resource.adapter.jdbc.xa.XAManagedConnection.destroy(XAManagedConnection.java:193)
        at 
org.jboss.resource.connectionmanager.InternalManagedConnectionPool.doDestroy(InternalManagedConnectionPool.java:268)
        at 
org.jboss.resource.connectionmanager.InternalManagedConnectionPool.removeTimedOut(InternalManagedConnectionPool.java:186)
        at org.jboss.resource.connectionmanager.IdleRemover$1.run(IdleRemover.java:70)
        at java.lang.Thread.run(Thread.java:479)

I suspect it's due to some sort of Oracle (!) or JBoss bug
which changes the connection transaction type
from local to global...

Thanks for considering the problem.




----------------------------------------------------------------------

Comment By: Igor Fedorenko (igorfie)
Date: 2002-09-25 06:24

Message:
Logged In: YES 
user_id=232950

Could you provide information about oracle server version, 
oracle jdbc driver version and driver type (thin/oci) and JBOSS 
version?


----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=376685&aid=614116&group_id=22866


-------------------------------------------------------
This sf.net email is sponsored by: DEDICATED SERVERS only $89!
Linux or FreeBSD, FREE setup, FAST network. Get your own server 
today at http://www.ServePath.com/indexfm.htm
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to