Bugs item #614116, was opened at 2002-09-24 19: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: Igor Fedorenko (igorfie)
Date: 2002-10-03 18:55

Message:
Logged In: YES 
user_id=232950

There is another problem with 3.2/40 which did not exist in 
3.0 and which could be a cause of your problems.

3.2/4.0 calls xares.end(xid, TMSUSPEND) to delist a 
connection from tx. This is done to be able to re-enlist the 
connection should the tx need it again. Oracle does not like 
TMSUSPEND and throws an exception.

To check if this is your problem change 
org.jboss.resource.connectionmanager.TxConnectionManager
 to use TMSUCCESS instead of TMSUSPEND and rerun 
your tests. If this does not help (i.e. you still get an exception 
with TMSUCCESS) could you please provide simple testcase 
that demonstrates the problem?


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

Comment By: Matt Cleveland (groovesoftware)
Date: 2002-10-03 08:49

Message:
Logged In: YES 
user_id=85088

I have been watching this bug for several days because I 
believe I am seeing the same error in a much different 
situation.  At least the oracle part of the stack trace I am 
seeing is exactly the same (stack trace is pasted below).  
Let me see if I can shed any light or at least add some 
information to the discussion.

First of all, the problem I am seeing does not occur in 3.0.2 
but it does occur in 3.2.0beta and 3.2.0 current CVS and 
CVS HEAD (4.0.0alpha).  However the workaround 
suggested by igorfie fixes it in 3.2.0 and 4.0.0 (more on this 
below).

The problem I am seeing does not in involve an MDB.  I am 
simply making Oracle updates from a stateless session 
bean.  I do not believe there is any concurrency involved 
because I am the only one executing tests against the JBoss 
installation I am testing with.  However I could be wrong 
about the concurrency since the servlet that makes the 
stateless session bean call is part of a frameset.

Also, the problem I am seeing does not (as far as I can tell) 
involve a rollback except for the one caused by this error.  In 
other words there is none of my code requesting a rollback 
and if it wasn't for this Oracle XA error I believe the 
transaction would commit succesfully.

The other notable factor is that the servlet involves a mixture 
of non-tx and xa operations on Oracle.  Let me explain.  
Before calling the bean the servlet makes some Oracle calls 
on a connection it gets from an 
org.jboss.resource.connectionmanager.NoTxConnectionMana
ger.  Then it calls the stateless session bean.  The stateless 
session bean does some more oracle work on a connection 
it gets from an 
org.jboss.resource.connectionmanager.XATxConnectionMana
ger.

I can work around the problem by setting 
TrackConnectionByTx=true on the XA connection manager 
as suggested by igorfie.  As igorfie says this will, "configure 
JBOSS not to use same xa resource in two 
concurrent transactions."  But I'm not really sure why this 
fixes it since as far as I can tell there is no concurrency 
problems involved in my case (although again I should say I 
might be wrong on that).  I am also unsure why I do not have 
this problem in 3.0.2.

It seems like this solution is reasonable and will not have any 
performance impact on our application as long as the 
connection pool is sized appropriately.  Does anyone see 
any performance issues with this workaround?

Based on my information I would like to suggest that the 
problem is not one of concurrency, but comes from some 
pattern of reuse of the Oracle connections which can be 
reproduced in concurrent and non-concurrent cases but that 
TrackConnectionByTx alters enough to fix.

Finally, here's my stack trace so that you can confirm that 
this is actually the same problem.  Note that the first  3 lines 
(the Oracle Part) are exactly the same as that reported by 
genman.

Hope this helps.

Matt

2002-10-03 12:00:43,793 WARN  
[org.jboss.tm.TransactionImpl] XAException: 
tx=TransactionImpl:XidImpl [FormatId=257, 
GlobalId=malt//11, 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.TransactionImpl.endResource
(TransactionImpl.java:1056)
    at org.jboss.tm.TransactionImpl.endResources
(TransactionImpl.java:1118)
    at org.jboss.tm.TransactionImpl.commit
(TransactionImpl.java:332)
    at org.jboss.ejb.plugins.TxInterceptorCMT.endTransaction
(TxInterceptorCMT.java:308)
    at 
org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions
(TxInterceptorCMT.java:194)
    at org.jboss.ejb.plugins.TxInterceptorCMT.invoke
(TxInterceptorCMT.java:66)
    at org.jboss.ejb.plugins.SecurityInterceptor.invoke
(SecurityInterceptor.java:130)
    at org.jboss.ejb.plugins.LogInterceptor.invoke
(LogInterceptor.java:205)
    at org.jboss.ejb.plugins.CleanShutdownInterceptor.invoke
(CleanShutdownInterceptor.java:255)
    at 
org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke
(ProxyFactoryFinderInterceptor.java:154)
    at org.jboss.ejb.StatelessSessionContainer.invoke
(StatelessSessionContainer.java:303)
    at org.jboss.ejb.Container.invoke(Container.java:671)
    at org.jboss.mx.server.MBeanServerImpl.invoke
(MBeanServerImpl.java:549)
    at org.jboss.invocation.local.LocalInvoker.invoke
(LocalInvoker.java:100)
    at org.jboss.invocation.InvokerInterceptor.invoke
(InvokerInterceptor.java:88)
    at org.jboss.proxy.TransactionInterceptor.invoke
(TransactionInterceptor.java:77)
    at org.jboss.proxy.SecurityInterceptor.invoke
(SecurityInterceptor.java:80)
    at org.jboss.proxy.ejb.StatelessSessionInterceptor.invoke
(StatelessSessionInterceptor.java:109)
    at org.jboss.proxy.ClientContainer.invoke
(ClientContainer.java:82)
    at $Proxy99.getAllBasicGuestInformation(Unknown 
Source)
    at 
com.synxis.srms.ejbs.dm.SrmsGuestInformationServiceTxHa
ndlerBean.getAllBasicGuestInformation
(SrmsGuestInformationServiceTxHandlerBean.java:726)
    at java.lang.reflect.Method.invoke(Native Method)
    at 
org.jboss.ejb.StatelessSessionContainer$ContainerInterceptor
.invoke(StatelessSessionContainer.java:606)
    at 
org.jboss.resource.connectionmanager.CachedConnectionInte
rceptor.invoke(CachedConnectionInterceptor.java:186)
    at 
org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.inv
oke(StatelessSessionInstanceInterceptor.java:77)
    at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext
(AbstractTxInterceptor.java:108)
    at 
org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions
(TxInterceptorCMT.java:214)
    at org.jboss.ejb.plugins.TxInterceptorCMT.invoke
(TxInterceptorCMT.java:66)
    at org.jboss.ejb.plugins.SecurityInterceptor.invoke
(SecurityInterceptor.java:130)
    at org.jboss.ejb.plugins.LogInterceptor.invoke
(LogInterceptor.java:205)
    at org.jboss.ejb.plugins.CleanShutdownInterceptor.invoke
(CleanShutdownInterceptor.java:255)
    at 
org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke
(ProxyFactoryFinderInterceptor.java:154)
    at org.jboss.ejb.StatelessSessionContainer.invoke
(StatelessSessionContainer.java:303)
    at org.jboss.ejb.Container.invoke(Container.java:671)
    at org.jboss.mx.server.MBeanServerImpl.invoke
(MBeanServerImpl.java:549)
    at org.jboss.invocation.local.LocalInvoker.invoke
(LocalInvoker.java:100)
    at org.jboss.invocation.InvokerInterceptor.invoke
(InvokerInterceptor.java:88)
    at org.jboss.proxy.TransactionInterceptor.invoke
(TransactionInterceptor.java:77)
    at org.jboss.proxy.SecurityInterceptor.invoke
(SecurityInterceptor.java:80)
    at org.jboss.proxy.ejb.StatelessSessionInterceptor.invoke
(StatelessSessionInterceptor.java:109)
    at org.jboss.proxy.ClientContainer.invoke
(ClientContainer.java:82)
    at $Proxy99.getAllBasicGuestInformation(Unknown 
Source)
    at 
com.synxis.srms.servlet.va.GuestInfo.GuestInfoName.lookup
Name(GuestInfoName.java:101)
    at 
com.synxis.srms.servlet.va.GuestInfo.GuestInfoFrameset.doR
ealPost(GuestInfoFrameset.java:76)
    at com.synxis.srms.servlet.SrmsServletBase.doPost
(SrmsServletBase.java:115)
    at com.synxis.srms.servlet.SrmsServletBase.doGet
(SrmsServletBase.java:144)
    at javax.servlet.http.HttpServlet.service
(HttpServlet.java:740)
    at javax.servlet.http.HttpServlet.service
(HttpServlet.java:853)
    at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilt
er(ApplicationFilterChain.java:247)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter
(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.StandardWrapperValve.invoke
(StandardWrapperValve.java:243)
    at org.apache.catalina.core.StandardPipeline.invokeNext
(StandardPipeline.java:566)
    at org.apache.catalina.core.StandardPipeline.invoke
(StandardPipeline.java:472)
    at org.apache.catalina.core.ContainerBase.invoke
(ContainerBase.java:943)
    at org.apache.catalina.core.StandardContextValve.invoke
(StandardContextValve.java:190)
    at org.apache.catalina.core.StandardPipeline.invokeNext
(StandardPipeline.java:566)
    at org.apache.catalina.valves.CertificatesValve.invoke
(CertificatesValve.java:246)
    at org.apache.catalina.core.StandardPipeline.invokeNext
(StandardPipeline.java:564)
    at org.apache.catalina.core.StandardPipeline.invoke
(StandardPipeline.java:472)
    at org.apache.catalina.core.ContainerBase.invoke
(ContainerBase.java:943)
    at org.apache.catalina.core.StandardContext.invoke
(StandardContext.java:2347)
    at org.apache.catalina.core.StandardHostValve.invoke
(StandardHostValve.java:180)
    at org.apache.catalina.core.StandardPipeline.invokeNext
(StandardPipeline.java:566)
    at org.apache.catalina.valves.ErrorDispatcherValve.invoke
(ErrorDispatcherValve.java:170)
    at org.apache.catalina.core.StandardPipeline.invokeNext
(StandardPipeline.java:564)
    at org.apache.catalina.valves.ErrorReportValve.invoke
(ErrorReportValve.java:170)
    at org.apache.catalina.core.StandardPipeline.invokeNext
(StandardPipeline.java:564)
    at org.apache.catalina.valves.AccessLogValve.invoke
(AccessLogValve.java:468)
    at org.apache.catalina.core.StandardPipeline.invokeNext
(StandardPipeline.java:564)
    at org.apache.catalina.core.StandardPipeline.invoke
(StandardPipeline.java:472)
    at org.apache.catalina.core.ContainerBase.invoke
(ContainerBase.java:943)
    at org.apache.catalina.core.StandardEngineValve.invoke
(StandardEngineValve.java:174)
    at org.apache.catalina.core.StandardPipeline.invokeNext
(StandardPipeline.java:566)
    at org.apache.catalina.core.StandardPipeline.invoke
(StandardPipeline.java:472)
    at org.apache.catalina.core.ContainerBase.invoke
(ContainerBase.java:943)
    at 
org.apache.catalina.connector.http.HttpProcessor.process
(HttpProcessor.java:1027)
    at org.apache.catalina.connector.http.HttpProcessor.run
(HttpProcessor.java:1125)
    at java.lang.Thread.run(Thread.java:479)






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

Comment By: Elias Ross (genman)
Date: 2002-10-01 23: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 21: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 13: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 14: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 14: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 09: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:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to