SimpleJTA is being tested with the following versions of Oracle:
Oracle RDMS Release |
Oracle9i Enterprise Edition Release 9.2.0.5.0 |
Oracle Thin JDBC driver |
Do not use Oracle RDBMS releases prior to 9.2.0.5 for XA transactions. I initially started with 9.2.0.1 but found bugs in the Oracle implementation. Upgrading to 9.2.0.5 resolved the issues.
The Oracle 10g driver is supposed to be faster because it implements all the XA logic in the driver itself. The 9.2 JDBC drivers use server side stored procedures. However, I found that the XA implementation in 10.1.0.2.0 driver is broken. It does not allow XAConnection.getConnection() to be invoked after XAResource.start().
Each release of Oracle's JDBC drivers appears to be different in terms of behaviour from previous releases. You have to be careful when switching from one version to another, as the XA implementation may not work correctly under all versions. So far I have found the 9.2.0.5 release to be most stable.
Oracle's XA implementation allows the same Connection to be used to local or global transactions. This is determined automatically. If a connection is enlisted in an XA transaction it switches to global mode. If you haven't enlisted the connection and execute any SQL, then it switches to local mode. To come out of local or global mode, you need to commit/rollback the local/global transaction as appropriate.
Oracle's XAResource implementation does not support joining an existing transaction branch with TMJOIN. A new branch has to be started. However, during prepare, Oracle marks the second branch as READONLY so it does not need to be committed.
JTA specifications allow an XAResource object to shared amongst multiple concurrent transactions with the restriction that the resource can be enlisted with a single transaction at a point in time. Resource sharing amonst multiple transactions appears to cause a problem in Oracle in a multi-threaded environment. Therefore, SimpleJTA is configured to defer the reuse of an XAResource object by other transactions until the existing transaction is completed, i.e., either committed or rolled back.
SimpleJTA can be configured to perform restart recovery in two different ways. In the first method, all databases participating in transactions are setup with a special Oracle userid that will be used purely for recovery purposes. This Oracle userid needs to be granted following privileges:
grant select on dba_pending_transactions to <user>; grant select on dba_2pc_pending to <user>; grant force any transaction to <user>;
Please note that the special recovery id must be registered with
SimpleJTA using the TMGR.recoveryUser
and TMGR.recoveryPassword
properties as described in the User Manual
.
In the second method, recovery is performed using the Oracle userids that were used to start the transactions. No special recovery id is setup. In this scenario, all Oracle userids that will participate in global transactions must be granted following privileges:
grant select on dba_pending_transactions to <user>; grant select on dba_2pc_pending to <user>;
I recommend that you setup a special recovery id on all Oracle databases.
SimpleJTA is being tested with the following releases of Derby.
Apache Derby release |
|
Apache Derby embedded drivers |
org.apache.derby.jdbc.EmbeddedDriver |
Apache Derby Network Client |
Apache Derby supports XA transactions in the embedded drivers. A new Client driver has been contributed by IBM to the Apache Derby project, however, my test suite fails when using this.
Apache Derby allows the same Connection object to be used for local or global transactions.
It seems that XAResource.start() with TMJOIN is supported but not within the same thread. SimpleJTA is configured so that it does not use TMJOIN with Derby.
JTA specifications allow an XAResource object to shared amongst multiple concurrent transactions with the restriction that the resource can be enlisted with a single transaction only at a point in time. This appears to work fine in Derby. Therefore, SimpleJTA is configured to allow an XAResource object to be used by other transactions after it has been disassociated from a transaction, i.e., end() has been invoked.
Apache Derby does not require any special privileges to be granted for recovery. Hence, there is no need to setup special recovery id or to grant any specific privileges.