[ 
https://issues.apache.org/jira/browse/DERBY-4232?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12710407#action_12710407
 ] 

Knut Anders Hatlen commented on DERBY-4232:
-------------------------------------------

What makes this fail, is the following code in 
DRDAXAProtocol.startXATransaction() on the server:

                        } else if (xaTimeout != -1 && xaflags != 
XAResource.TMNOFLAGS) {
                                // According the DRDA spec if the value of 
timeout was specified
                                // a TMNOFLAGS have to be used
                                throw new XAException(XAException.XAER_PROTO);

It is the SYNCCTL section in volume 3 of the DRDA spec that says that the 
timeout property should not be present when XAFLAGS is not TMNOFLAGS. I don't 
know if this means that XAResource.start(TMJOIN) should fail if a timeout is 
set, or if it simply means that the client shouldn't send the timeout value if 
the flag is TMJOIN or TMRESUME.

> 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