Call XAResource.setTransactionTimeout() makes XAResource.start() fail with the 
client dirver
--------------------------------------------------------------------------------------------

                 Key: DERBY-4232
                 URL: https://issues.apache.org/jira/browse/DERBY-4232
             Project: Derby
          Issue Type: Bug
          Components: JDBC
    Affects Versions: 10.4.2.0
            Reporter: Simon Meng


Got below error message when running an XA prolgram with derby. 
org.apache.derby.client.am.XaException: XAER_PROTO : Error executing a 
XAResource.start(), server returned XAER_PROTO.
        at org.apache.derby.client.net.NetXAResource.throwXAException(Unknown 
Source)
        at org.apache.derby.client.net.NetXAResource.start(Unknown Source)
        at TestDerbyXA.process(TestDerbyXA.java:186)
        at TestDerbyXA.main(TestDerbyXA.java:43)
Caused by: org.apache.derby.client.am.SqlException: Error executing a 
XAResource.start(), server returned XAER_PROTO.
        at 
org.apache.derby.client.net.NetXAResource.xaRetValErrorAccumSQL(Unknown Source)
        ... 3 more

Below is the example program I used. Note: The program will succeed if comment 
out line 147 - setTransactionTimeout. Does that means call 
XAResource.setTransactionTimeout() caused the failure?
I use Apache Derby Network Server - 10.4.2.0 - (689064). The same program works 
fine with another version Apache Derby Network Server - 10.2.2.0 - (485682). It 
looks like there is a regression between the two versions.

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.XAConnection;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;

import org.apache.derby.jdbc.ClientXADataSource;

public class TestDerbyXA {

        ClientXADataSource xaDSLocal = null;

        ClientXADataSource xaDSRemote = null;

        public TestDerbyXA() {
                // Create two XA data sources.
                xaDSLocal = new ClientXADataSource();
                xaDSLocal.setServerName("localhost");
                xaDSLocal.setPortNumber(1527);
                xaDSLocal.setDatabaseName("testdb");
                xaDSLocal.setUser("app");
                xaDSLocal.setPassword("derby");

                xaDSRemote = new ClientXADataSource();
                xaDSRemote.setServerName("localhost");
                xaDSRemote.setPortNumber(1527);
                xaDSRemote.setDatabaseName("testdb");
                xaDSRemote.setUser("app");
                xaDSRemote.setPassword("derby");
                // xaDSRemote = xaDSLocal;
        }

        public static void main(String[] args) throws Exception {
                TestDerbyXA testObj = new TestDerbyXA();
                testObj.dropTable("tablea");
                testObj.createTable("CREATE TABLE tablea (col1 INT, col2 
VARCHAR(32))");
                testObj.dropTable("tableb");
                testObj.createTable("CREATE TABLE tableb (col1 INT, col2 
VARCHAR(32))");
                testObj.process();
        }

        public void dropTable(String tableName) throws Exception {
                Connection conn = null;
                Statement stmt = null;

                try {
                        conn = xaDSLocal.getConnection();
                        stmt = conn.createStatement();
                        stmt.executeUpdate("DROP TABLE " + tableName);
                        System.out.println("Drop table " + tableName + " 
succeed.");
                } catch (SQLException sqle) {
                        System.out.println("Drop table " + tableName + " 
failed.");
                        sqle.printStackTrace();
                } finally {
                        // ============ Close JDBC objects, including the 
connection =======
                        if (stmt != null) {
                                try {
                                        stmt.close();
                                        stmt = null;
                                } catch (SQLException e) {
                                }
                        }
                        if (conn != null) {
                                try {
                                        conn.close();
                                        conn = null;
                                } catch (SQLException e) {
                                }
                        }
                }
        }

        public void createTable(String DDL) throws Exception {
                Connection conn = null;
                Statement stmt = null;

                try {
                        conn = xaDSLocal.getConnection();
                        stmt = conn.createStatement();
                        stmt.executeUpdate(DDL);
                        System.out.println(DDL + " succeed.");
                } catch (SQLException sqle) {
                        System.out.println(DDL + " failed.");
                        sqle.printStackTrace();
                } finally {
                        // ============ Close JDBC objects, including the 
connection =======
                        if (stmt != null) {
                                try {
                                        stmt.close();
                                        stmt = null;
                                } catch (SQLException e) {
                                }
                        }
                        if (conn != null) {
                                try {
                                        conn.close();
                                        conn = null;
                                } catch (SQLException e) {
                                }
                        }
                }
        }

        public void process() throws Exception {
                Connection connLocal = null;
                Connection connRemote = null;
                int rows = 0;
                PreparedStatement pstmtLocal = null;
                PreparedStatement pstmtRemote = null;
                XAConnection xaConnLocal = null;
                XAConnection xaConnRemote = null;
                XAResource xarLocal = null;
                XAResource xarRemote = null;
                Xid xidLocal = null;
                Xid xidRemote = null;
                try {
                        xaConnLocal = xaDSLocal.getXAConnection();
                        xaConnRemote = xaDSRemote.getXAConnection();
                        connLocal = xaConnLocal.getConnection();
                        connRemote = xaConnRemote.getConnection();
                        xarLocal = xaConnLocal.getXAResource();
                        xarRemote = xaConnRemote.getXAResource();

                        // Create the Xids

                        // Create the global ID
                        byte[] globalTransactionId1 = new byte[64];
                        globalTransactionId1[0] = (byte) 1;
                        byte[] globalTransactionId2 = new byte[64];
                        globalTransactionId2[0] = (byte) 2;

                        // Create the local branch ID
                        byte[] branchQualifierLocal = new byte[64];
                        branchQualifierLocal[0] = (byte) 1;
                        xidLocal = new XidImpl(globalTransactionId1, 
branchQualifierLocal, 0x1234);

                        // Create the remote branch ID
                        byte[] branchQualifierRemote = new byte[64];
                        branchQualifierRemote[0] = (byte) 2;
                        xidRemote = new XidImpl(globalTransactionId2, 
branchQualifierRemote, 0x1234);

                        // Database operations on the local branch, suspend 
local branch
                        xarLocal.setTransactionTimeout(500);  //!!! The failure 
will disappear if comment out this line.
                        connLocal.setAutoCommit(false);
                        xarLocal.start(xidLocal, XAResource.TMNOFLAGS);

                        pstmtLocal = connLocal
                                        .prepareStatement("INSERT INTO tablea 
(col1, col2) VALUES (?, ?)");
                        pstmtLocal.setInt(1, 1);
                        pstmtLocal.setString(2, "insert first rec to tablea");
                        rows = pstmtLocal.executeUpdate();
                        System.out.println(rows + " rows inserted to tablea");
                        pstmtLocal.close();
                        pstmtLocal = null;

                        xarLocal.end(xidLocal, XAResource.TMSUCCESS);
                        connLocal.setAutoCommit(true);

                        // Database operation on the remote branch, commit 
remote branch
                        xarRemote.setTransactionTimeout(500);
                        connRemote.setAutoCommit(false);
                        xarRemote.start(xidRemote, XAResource.TMNOFLAGS);

                        pstmtRemote = connRemote
                                        .prepareStatement("INSERT INTO tableb 
(col1, col2) VALUES (?, ?)");
                        pstmtRemote.setInt(1, 2);
                        pstmtRemote.setString(2, "insert second rec to tableb");
                        rows = pstmtRemote.executeUpdate();
                        System.out.println(rows + " rows inserted to tableb");
                        pstmtRemote.close();
                        pstmtRemote = null;

                        xarRemote.end(xidRemote, XAResource.TMSUCCESS);
                        connRemote.setAutoCommit(true);

                        System.out.println("commit remote branch");
                        xarRemote.commit(xidRemote, true);

                        // Resume the local branch and do some database 
operation, commit local branch
                        xarLocal.setTransactionTimeout(500);
                        connLocal.setAutoCommit(false);
                        xarLocal.start(xidLocal, XAResource.TMJOIN);

                        pstmtLocal = connLocal
                                        .prepareStatement("INSERT INTO tablea 
(col1, col2) VALUES (?, ?)");
                        pstmtLocal.setInt(1, 3);
                        pstmtLocal.setString(2, "insert third rec to tablea");
                        rows = pstmtLocal.executeUpdate();
                        System.out.println(rows + " rows inserted to tablea");
                        pstmtLocal.close();
                        pstmtLocal = null;

                        xarLocal.end(xidLocal, XAResource.TMSUCCESS);
                        connLocal.setAutoCommit(true);

                        System.out.println("commit local branch");
                        xarLocal.commit(xidLocal, true);

                        // Close the resources
                        connLocal.close();
                        connLocal = null;
                        connRemote.close();
                        connRemote = null;
                        xaConnLocal.close();
                        xaConnLocal = null;
                        xaConnRemote.close();
                        xaConnRemote = null;
                } catch (SQLException e) {
                        System.err.println("SQL Error: " + e.getMessage());
                        e.printStackTrace();
                } catch (XAException e) {
                        System.err.println("XA Error: " + e.getMessage());
                        e.printStackTrace();
                } finally {
                        if (pstmtLocal != null)
                                try {
                                        pstmtLocal.close();
                                        pstmtLocal = null;
                                } catch (SQLException ignore) {
                                }
                        if (pstmtRemote != null)
                                try {
                                        pstmtRemote.close();
                                        pstmtRemote = null;
                                } catch (SQLException ignore) {
                                }
                        if (connLocal != null)
                                try {
                                        connLocal.close();
                                        connLocal = null;
                                } catch (SQLException ignore) {
                                }
                        if (connRemote != null)
                                try {
                                        connRemote.close();
                                        connRemote = null;
                                } catch (SQLException ignore) {
                                }
                        if (xaConnLocal != null)
                                try {
                                        xaConnLocal.close();
                                        xaConnLocal = null;
                                } catch (SQLException ignore) {
                                }
                        if (xaConnRemote != null)
                                try {
                                        xaConnRemote.close();
                                        xaConnRemote = null;
                                } catch (SQLException ignore) {
                                }
                }
        }
}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to