You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-dev@db.apache.org by Mamta Satoor <ma...@Remulak.Net> on 2004/09/18 16:49:50 UTC

Bug in Derby XA code?

Hi,

Let me start by first giving the backgroup information on XA in Derby.
In Debry, by default, the cursors are held open after a commit.But
holdable curosrs are not supported in XA transactions in Derby,
therefore cursors should be opened with holdability false when
working with XA transactions.

Similarly, in Derby, as per JDBC specifications, auto-commit is
set to true by default. But when in a XA transaction, the
auto-commit mode is set to false automatically.

So, when an XA transaction is started on a XA connection, Derby
code internally switches the connection's holdability to
CLOSE_CURSORS_AT_COMMIT and autocommit to false. Eg
    EmbeddedXADataSource dscsx = new EmbeddedXADataSource();
    dscsx.setDatabaseName("wombat");
    XAConnection xac = dscsx.getXAConnection("fred", "wilma");
    XAResource xr = xac.getXAResource();
    Xid xid = getXid(25, (byte) 21, (byte) 01);
    Connection conn1 = xac.getConnection();
    System.out.println("By default, autocommit is " +
conn1.getAutoCommit() + " for a connection");
    System.out.println("Default holdability for a connection is
HOLD_CURSORS_OVER_COMMIT");
    System.out.println("CONNECTION(not in xa transaction yet)
HOLDABILITY " + (conn1.getHoldability() ==
ResultSet.HOLD_CURSORS_OVER_COMMIT));
    //start a global transaction and default holdability and autocommit
will be switched to match Derby XA restrictions
    xr.start(xid, XAResource.TMNOFLAGS);
    System.out.println("Notice that autocommit now is " +
conn1.getAutoCommit() + " for connection because it is part of the
global transaction");
    System.out.println("Notice that connection's holdability at this
point is CLOSE_CURSORS_AT_COMMIT because it is part of the global
transaction");
    System.out.println("CONNECTION(in xa transaction) HOLDABILITY " +
(conn1.getHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT));
    xr.end(xid, XAResource.TMSUCCESS);
The output for the above piece of code is
    By default, autocommit is true for a connection
    Default holdability for a connection is HOLD_CURSORS_OVER_COMMIT
    CONNECTION(not in xa transaction yet) HOLDABILITY true
    Notice that autocommit now is false for connection because it is
part of the global transaction
    Notice that connection's holdability at this point is
CLOSE_CURSORS_AT_COMMIT because it is part of the global transaction
    CONNECTION(in xa transaction) HOLDABILITY false
As we can see from the output that Derby code switches the holdability
and autocommit of the connection to match the restrictions imposed on
XA transactions.

But I think there is a bug in Derby when the user code tries to get the
Connection object from XAConnection "inside" the global transaction.
In this case, the Connection object gets created with un-supported
holdability. Look at the following piece of code and it's output to
see what exactly happens
    EmbeddedXADataSource dscsx = new EmbeddedXADataSource();
    dscsx.setDatabaseName("wombat");
    XAConnection xac = dscsx.getXAConnection("fred", "wilma");
    XAResource xr = xac.getXAResource();
    xid = getXid(27, (byte) 21, (byte) 01);
    xr.start(xid, XAResource.TMNOFLAGS);
    conn1 = xac.getConnection();
    System.out.println("This is a bug. Connection's holdability should
have been CLOSE_CURSORS_AT_COMMIT since it is in the global
transaction");
    System.out.println("CONNECTION(in xa transaction) HOLDABILITY " +
(conn1.getHoldability() == ResultSet.HOLD_CURSORS_OVER_COMMIT));
    System.out.println("Autocommit on Connection inside global
transaction has been set correctly to " + conn1.getAutoCommit());
    xr.end(xid, XAResource.TMSUCCESS);
The output for the above piece of code is
    This is a bug. Connection's holdability should have been
CLOSE_CURSORS_AT_COMMIT since it is in the global transaction
    CONNECTION(in xa transaction) HOLDABILITY true
    Autocommit on Connection inside global transaction has been set
correctly to false


Any comments?
Mamta