[jbossts-issues] [JBoss JIRA] (JBTM-2264) Error enlisting second xa resource on the same oracle instance but other schema

Tom Jenkinson (JIRA) issues at jboss.org
Fri Oct 3 08:44:11 EDT 2014

    [ https://issues.jboss.org/browse/JBTM-2264?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13008490#comment-13008490 ] 

Tom Jenkinson commented on JBTM-2264:

Hi Evgeniy,

I have raised a pull request for this in our transactional driver code. I have also deployed a snapshot version of Narayana with the change already in there for you to have a go with. I have tested it locally (extensively) and it works for me. I can see the SNAPSHOT over here: https://repository.jboss.org/nexus/content/groups/public/org/jboss/narayana/jta/narayana-jta/5.0.4.Final-SNAPSHOT/. All you should need to do is change your pom to this version.

Now for some background. BTM and Atomikos are not strictly spec compliant in my mind as their core transaction processing engine performs simple pointer comparison to determine if two XAResources are equivalent rather than the spec defined approach of using isSameRM. You can see the pointer comparison for yourself over here: https://github.com/bitronix/btm/blob/master/btm/src/main/java/bitronix/tm/internal/XAResourceManager.java#L194
You can see where the spec has pseudo code that demonstrates how the transaction manager is intended to use isSameRM in section "3.4.9 Identifying Resource Manager Instance" over here: https://jcp.org/en/jsr/detail?id=907

If two XAR are not equivalent you are meant to generate a new Xid for the branch and call start with TMNOFLAGS (as BTM/Atomikos will in this case, even though its technically the same RM) and if they are equivalent you use the same Xid and call start with TMJOIN (as we do).

It turns out that there are a number of resource managers that return true to isSameRM but cannot handle the TMJOIN flag. It also turns out that this is a known issue with some of the drivers and Ironjacamar (Red Hats JCA implementation in Wildfly) already works around that for a number of drivers by wrapping their XAResources with an is-same-rm-override flag that returns false. The impact of this is that although your test would work in WildFly, there is a slight performance impact as the RM has two branches, plus should you touch the same tables you may be able to deadlock. Anyway, as you were using transactional driver rather than ironjacamar you have hit this issue. I have effectively backported that IJ workaround for a number of drivers which are also not compliant to our transactional driver code.

The reason we haven't gone to pointer comparison is:
1. Spec compliance - we don't break that
2. There is an issue with overriding isSameRM which affects app servers performing a process known as transaction inflow. Due to limitations with the transaction inflow API (discussed at length elsewhere, for example https://issues.jboss.org/browse/JBTM-622) a transaction manager is not permitted to generate different Xids for resources. As such if we override the same rm report from the RM, RMs which correctly implement isSameRM and accept TMJOIN would be unfairly penalised as they would get:
xaResource1.start(xid1, TMNOFLAGS)
xaResource2.start(xid1, TMNOFLAGS)
Which is a protocol error.

Hope it helps,

> Error enlisting second xa resource on the same oracle instance but other schema
> -------------------------------------------------------------------------------
>                 Key: JBTM-2264
>                 URL: https://issues.jboss.org/browse/JBTM-2264
>             Project: JBoss Transaction Manager
>          Issue Type: Bug
>          Components: JTA
>    Affects Versions: 5.0.3
>            Reporter: Evgeniy Smelik
>            Assignee: Tom Jenkinson
>         Attachments: sscce.zip, sscce.zip, test.log
> I've got an exception {{java.sql.SQLException: ConnectionImple.registerDatabase - ARJUNA017017: enlist of resource failed}} while preparing statement in the second connection within the same oracle instance but other schema.
> Whole stack trace:
> {noformat}
> oracle.jdbc.xa.OracleXAException
> 	at oracle.jdbc.xa.OracleXAResource.checkError(OracleXAResource.java:1110)
> 	at oracle.jdbc.xa.client.OracleXAResource.start(OracleXAResource.java:240)
> 	at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.enlistResource(TransactionImple.java:741)
> 	at com.arjuna.ats.internal.jdbc.ConnectionImple.registerDatabase(ConnectionImple.java:983)
> 	at com.arjuna.ats.internal.jdbc.ConnectionImple.prepareStatement(ConnectionImple.java:179)
> 	at SimpleJdbcTest.insert(SimpleJdbcTest.java:46)
> 	at SimpleJdbcTest.main(SimpleJdbcTest.java:36)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> 	at java.lang.reflect.Method.invoke(Method.java:606)
> 	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
> java.sql.SQLException: ConnectionImple.registerDatabase - ARJUNA017017: enlist of resource failed
> 	at com.arjuna.ats.internal.jdbc.ConnectionImple.registerDatabase(ConnectionImple.java:1003)
> 	at com.arjuna.ats.internal.jdbc.ConnectionImple.prepareStatement(ConnectionImple.java:179)
> 	at SimpleJdbcTest.insert(SimpleJdbcTest.java:46)
> 	at SimpleJdbcTest.main(SimpleJdbcTest.java:36)
> {noformat}
> (Detail log and SSCCE are attached).
> I use jboss transaction manager in standaloine application just to test jboss JTA implementation. The same code works well if one and second data sources use own (different) database instances.
> I note that atomikos and bitronix JTA implementation works correctly in the same environment irrespectively single oracle instance is used or not.
> I found similar problem [here|http://stackoverflow.com/questions/23617179/jboss-6-1-unable-to-get-connection-from-pool].

This message was sent by Atlassian JIRA

More information about the jbossts-issues mailing list