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 "Kathey Marsden (JIRA)" <de...@db.apache.org> on 2006/02/13 07:25:57 UTC

[jira] Created: (DERBY-960) xa_commit results in XAER_NOTA on readonly transaction after xa_prepare returns XA_OK

xa_commit results in  XAER_NOTA  on readonly transaction after xa_prepare returns XA_OK
---------------------------------------------------------------------------------------

         Key: DERBY-960
         URL: http://issues.apache.org/jira/browse/DERBY-960
     Project: Derby
        Type: Bug
    Versions: 10.1.2.3, 10.1.3.0, 10.2.0.0, 10.1.2.2    
    Reporter: Kathey Marsden
 Assigned to: Kathey Marsden 
     Fix For: 10.2.0.0, 10.1.3.0, 10.1.2.3


xa_commit results in  XAER_NOTA  on readonly transaction after xa_prepare returns XA_OK
Two phase commit on a read only transaction causes the following error:

Exception in thread "main" org.apache.derby.client.am.XaException: XAER_NOTA : Error executing a XAResource.commit(), Server returned XAER_NOTA
        at org.apache.derby.client.net.NetXAResource.throwXAException(NetXAResource.java:728)
        at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:216)
        at ReadOnlyTran.main(ReadOnlyTran.java:78)
Caused by: org.apache.derby.client.am.SqlException: Error executing a XAResource.commit(), Server returned XAER_NOTA
        at org.apache.derby.client.net.NetXAResource.xaRetValErrorAccumSQL(NetXAResource.java:976)
        at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:204)
        ... 1 more



The following program shows the problem:
Uncommenting the insert will cause the test to pass.

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
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 com.ibm.db2.jcc.DB2Xid;

class ReadOnlyTran  
{

   
    public static void main (String args [])throws Exception 
    {
    	//org.apache.derby.jdbc.ClientConnectionPoolDataSource ds = new org.apache.derby.jdbc.ClientConnectionPoolDataSource();
    	org.apache.derby.jdbc.ClientXADataSource ds = new 
		org.apache.derby.jdbc.ClientXADataSource();
    	//org.apache.derby.jdbc.EmbeddedXADataSource ds = new 
		//org.apache.derby.jdbc.EmbeddedXADataSource();
    	Connection conn = null;
    	ds.setDatabaseName("sample");
		ds.setTraceFile("trace.out");
    	ds.setConnectionAttributes("create=true");

         conn = ds.getConnection();
        PreparedStatement ps1 = null;
         try
         {
             DatabaseMetaData md = conn.getMetaData() ;
             
System.out.println(md.getDatabaseProductVersion());
             System.out.println(md.getDatabaseProductName());
             ps1 = conn.prepareStatement("CREATE TABLE TAB1(COL1 INT NOT NULL)");
             ps1.executeUpdate();
        	 System.out.println("done creating  table");
             conn.commit ();
         } catch (SQLException x)
         {
             System.out.println ("table already exists");
         }                 
        
        XAConnection pc1 = ds.getXAConnection();
        XAResource xar1 = pc1.getXAResource();
        Xid xid1 = createXid(11);
        xar1.start(xid1, XAResource.TMNOFLAGS);
        Connection conn1 = pc1.getConnection();             
        doSelect(conn1, 50);
		//doInsert(conn1);
        conn1.close();
        xar1.end(xid1, XAResource.TMSUCCESS);

        int prp1 = xar1.prepare(xid1);

        System.out.println("XAResource.XA_RDONLY" + 
XAResource.XA_RDONLY);
        System.out.println("XAResource.XA_OK" + 
XAResource.XA_OK);
        System.out.println("prp1 is: " + prp1);
        // Commit transaction
        if (prp1 == XAResource.XA_OK)
           xar1.commit(xid1, false);

        // Close physical connection
        pc1.close();
      }
  
    
    private static void doSelect(Connection conn, int deptno) 
throws SQLException 
    {
        Statement stmt = conn.createStatement();
        ResultSet rset1 = stmt.executeQuery("select * from tab1");
        while (rset1.next())
        {
        	System.out.println("==>: " + rset1.getString(1));
        }
        
        stmt.close();
        stmt = null;
    }

	private static void doInsert(Connection conn) throws SQLException
	{
        Statement stmt = conn.createStatement();
		stmt.executeUpdate("Insert into tab1 values(1)");
		stmt.close();
	}
    
    static Xid createXid(int bids) throws XAException {
        byte[] gid = new byte[1];
        gid[0] = (byte) 9;
        byte[] bid = new byte[1];
        bid[0] = (byte) bids;
        byte[] gtrid = new byte[64];
        byte[] bqual = new byte[64];
        System.arraycopy(gid, 0, gtrid, 0, 1);
        System.arraycopy(bid, 0, bqual, 0, 1);
        Xid xid = new DB2Xid(0x1234, gtrid, bqual);
        return xid;
    }
}


-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Updated: (DERBY-960) Client xa prepare returns XA_OK instead of XA_RDONLY for a read only transaction

Posted by "Kathey Marsden (JIRA)" <de...@db.apache.org>.
     [ http://issues.apache.org/jira/browse/DERBY-960?page=all ]

Kathey Marsden updated DERBY-960:
---------------------------------

        Summary: Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction  (was: xa_commit results in  XAER_NOTA  on readonly transaction after xa_prepare returns XA_OK)
    Description: 

Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction

The code below checks the return value of XaResource.prepare to decide whether to commit the transaction.   The prepare return value is XA_OK ( 0)  for client when it should be XA_RDONLY(3)

D>java ReadOnlyTran derbycli
10.2.0.0 alpha
Apache Derby
Apache Derby Network Client JDBC Driver
table already exists
==>: 1
XAResource.XA_RDONLY3
XAResource.XA_OK0
prp1 is: 0
Exception in thread "main" org.apache.derby.client.am.XaException: XAER_NOTA : Error executing a XAResource.commit(), Server returned XAER_NOTA
        at org.apache.derby.client.net.NetXAResource.throwXAException(NetXAResource.java:728)
        at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:216)
        at ReadOnlyTran.main(ReadOnlyTran.java:94)
Caused by: org.apache.derby.client.am.SqlException: Error executing a XAResource.commit(), Server returned XAER_NOTA
        at org.apache.derby.client.net.NetXAResource.xaRetValErrorAccumSQL(NetXAResource.java:976)
        at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:204)
        ... 1 more
D>

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
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 com.ibm.db2.jcc.DB2Xid;

class ReadOnlyTran  
{

   
    public static void main (String args [])throws Exception 
    {
    	//org.apache.derby.jdbc.ClientConnectionPoolDataSource ds = new org.apache.derby.jdbc.ClientConnectionPoolDataSource();
    	org.apache.derby.jdbc.ClientXADataSource ds = new 
		org.apache.derby.jdbc.ClientXADataSource();
    	//org.apache.derby.jdbc.EmbeddedXADataSource ds = new 
		//org.apache.derby.jdbc.EmbeddedXADataSource();
    	Connection conn = null;
    	ds.setDatabaseName("sample");
		ds.setTraceFile("trace.out");
    	ds.setConnectionAttributes("create=true");

         conn = ds.getConnection();
        PreparedStatement ps1 = null;
         try
         {
             DatabaseMetaData md = conn.getMetaData() ;
             
System.out.println(md.getDatabaseProductVersion());
             System.out.println(md.getDatabaseProductName());
             ps1 = conn.prepareStatement("CREATE TABLE TAB1(COL1 INT NOT NULL)");
             ps1.executeUpdate();
        	 System.out.println("done creating  table");
             conn.commit ();
         } catch (SQLException x)
         {
             System.out.println ("table already exists");
         }                 
        
        XAConnection pc1 = ds.getXAConnection();
        XAResource xar1 = pc1.getXAResource();
        Xid xid1 = createXid(11);
        xar1.start(xid1, XAResource.TMNOFLAGS);
        Connection conn1 = pc1.getConnection();             
        doSelect(conn1, 50);
		//doInsert(conn1);
        conn1.close();
        xar1.end(xid1, XAResource.TMSUCCESS);

        int prp1 = xar1.prepare(xid1);

        System.out.println("XAResource.XA_RDONLY" + 
XAResource.XA_RDONLY);
        System.out.println("XAResource.XA_OK" + 
XAResource.XA_OK);
        System.out.println("prp1 is: " + prp1);
        // Commit transaction
        if (prp1 == XAResource.XA_OK)
           xar1.commit(xid1, false);

        // Close physical connection
        pc1.close();
      }
  
    
    private static void doSelect(Connection conn, int deptno) 
throws SQLException 
    {
        Statement stmt = conn.createStatement();
        ResultSet rset1 = stmt.executeQuery("select * from tab1");
        while (rset1.next())
        {
        	System.out.println("==>: " + rset1.getString(1));
        }
        
        stmt.close();
        stmt = null;
    }

	private static void doInsert(Connection conn) throws SQLException
	{
        Statement stmt = conn.createStatement();
		stmt.executeUpdate("Insert into tab1 values(1)");
		stmt.close();
	}
    
    static Xid createXid(int bids) throws XAException {
        byte[] gid = new byte[1];
        gid[0] = (byte) 9;
        byte[] bid = new byte[1];
        bid[0] = (byte) bids;
        byte[] gtrid = new byte[64];
        byte[] bqual = new byte[64];
        System.arraycopy(gid, 0, gtrid, 0, 1);
        System.arraycopy(bid, 0, bqual, 0, 1);
        Xid xid = new DB2Xid(0x1234, gtrid, bqual);
        return xid;
    }
}


  was:
xa_commit results in  XAER_NOTA  on readonly transaction after xa_prepare returns XA_OK
Two phase commit on a read only transaction causes the following error:

Exception in thread "main" org.apache.derby.client.am.XaException: XAER_NOTA : Error executing a XAResource.commit(), Server returned XAER_NOTA
        at org.apache.derby.client.net.NetXAResource.throwXAException(NetXAResource.java:728)
        at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:216)
        at ReadOnlyTran.main(ReadOnlyTran.java:78)
Caused by: org.apache.derby.client.am.SqlException: Error executing a XAResource.commit(), Server returned XAER_NOTA
        at org.apache.derby.client.net.NetXAResource.xaRetValErrorAccumSQL(NetXAResource.java:976)
        at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:204)
        ... 1 more



The following program shows the problem:
Uncommenting the insert will cause the test to pass.

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
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 com.ibm.db2.jcc.DB2Xid;

class ReadOnlyTran  
{

   
    public static void main (String args [])throws Exception 
    {
    	//org.apache.derby.jdbc.ClientConnectionPoolDataSource ds = new org.apache.derby.jdbc.ClientConnectionPoolDataSource();
    	org.apache.derby.jdbc.ClientXADataSource ds = new 
		org.apache.derby.jdbc.ClientXADataSource();
    	//org.apache.derby.jdbc.EmbeddedXADataSource ds = new 
		//org.apache.derby.jdbc.EmbeddedXADataSource();
    	Connection conn = null;
    	ds.setDatabaseName("sample");
		ds.setTraceFile("trace.out");
    	ds.setConnectionAttributes("create=true");

         conn = ds.getConnection();
        PreparedStatement ps1 = null;
         try
         {
             DatabaseMetaData md = conn.getMetaData() ;
             
System.out.println(md.getDatabaseProductVersion());
             System.out.println(md.getDatabaseProductName());
             ps1 = conn.prepareStatement("CREATE TABLE TAB1(COL1 INT NOT NULL)");
             ps1.executeUpdate();
        	 System.out.println("done creating  table");
             conn.commit ();
         } catch (SQLException x)
         {
             System.out.println ("table already exists");
         }                 
        
        XAConnection pc1 = ds.getXAConnection();
        XAResource xar1 = pc1.getXAResource();
        Xid xid1 = createXid(11);
        xar1.start(xid1, XAResource.TMNOFLAGS);
        Connection conn1 = pc1.getConnection();             
        doSelect(conn1, 50);
		//doInsert(conn1);
        conn1.close();
        xar1.end(xid1, XAResource.TMSUCCESS);

        int prp1 = xar1.prepare(xid1);

        System.out.println("XAResource.XA_RDONLY" + 
XAResource.XA_RDONLY);
        System.out.println("XAResource.XA_OK" + 
XAResource.XA_OK);
        System.out.println("prp1 is: " + prp1);
        // Commit transaction
        if (prp1 == XAResource.XA_OK)
           xar1.commit(xid1, false);

        // Close physical connection
        pc1.close();
      }
  
    
    private static void doSelect(Connection conn, int deptno) 
throws SQLException 
    {
        Statement stmt = conn.createStatement();
        ResultSet rset1 = stmt.executeQuery("select * from tab1");
        while (rset1.next())
        {
        	System.out.println("==>: " + rset1.getString(1));
        }
        
        stmt.close();
        stmt = null;
    }

	private static void doInsert(Connection conn) throws SQLException
	{
        Statement stmt = conn.createStatement();
		stmt.executeUpdate("Insert into tab1 values(1)");
		stmt.close();
	}
    
    static Xid createXid(int bids) throws XAException {
        byte[] gid = new byte[1];
        gid[0] = (byte) 9;
        byte[] bid = new byte[1];
        bid[0] = (byte) bids;
        byte[] gtrid = new byte[64];
        byte[] bqual = new byte[64];
        System.arraycopy(gid, 0, gtrid, 0, 1);
        System.arraycopy(bid, 0, bqual, 0, 1);
        Xid xid = new DB2Xid(0x1234, gtrid, bqual);
        return xid;
    }
}



Changed the summary and description to more accurately describe the problem.  From the description, for a while I was focussed on the commit, where in fact the problem is the return value from the prepare.

The source of the problem appears to be in DRDAXAProtocol.java  in prepareXATransaction where the return value is not properly returned.

> Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction
> ---------------------------------------------------------------------------------
>
>          Key: DERBY-960
>          URL: http://issues.apache.org/jira/browse/DERBY-960
>      Project: Derby
>         Type: Bug
>   Components: Network Client
>     Versions: 10.1.2.3, 10.1.3.0, 10.2.0.0, 10.1.2.2
>     Reporter: Kathey Marsden
>     Assignee: Kathey Marsden
>      Fix For: 10.2.0.0, 10.1.3.0, 10.1.2.3
>  Attachments: ReadOnlyTran.zip
>
> Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction
> The code below checks the return value of XaResource.prepare to decide whether to commit the transaction.   The prepare return value is XA_OK ( 0)  for client when it should be XA_RDONLY(3)
> D>java ReadOnlyTran derbycli
> 10.2.0.0 alpha
> Apache Derby
> Apache Derby Network Client JDBC Driver
> table already exists
> ==>: 1
> XAResource.XA_RDONLY3
> XAResource.XA_OK0
> prp1 is: 0
> Exception in thread "main" org.apache.derby.client.am.XaException: XAER_NOTA : Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.throwXAException(NetXAResource.java:728)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:216)
>         at ReadOnlyTran.main(ReadOnlyTran.java:94)
> Caused by: org.apache.derby.client.am.SqlException: Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.xaRetValErrorAccumSQL(NetXAResource.java:976)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:204)
>         ... 1 more
> D>
> import java.sql.Connection;
> import java.sql.DatabaseMetaData;
> import java.sql.PreparedStatement;
> import java.sql.ResultSet;
> 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 com.ibm.db2.jcc.DB2Xid;
> class ReadOnlyTran  
> {
>    
>     public static void main (String args [])throws Exception 
>     {
>     	//org.apache.derby.jdbc.ClientConnectionPoolDataSource ds = new org.apache.derby.jdbc.ClientConnectionPoolDataSource();
>     	org.apache.derby.jdbc.ClientXADataSource ds = new 
> 		org.apache.derby.jdbc.ClientXADataSource();
>     	//org.apache.derby.jdbc.EmbeddedXADataSource ds = new 
> 		//org.apache.derby.jdbc.EmbeddedXADataSource();
>     	Connection conn = null;
>     	ds.setDatabaseName("sample");
> 		ds.setTraceFile("trace.out");
>     	ds.setConnectionAttributes("create=true");
>          conn = ds.getConnection();
>         PreparedStatement ps1 = null;
>          try
>          {
>              DatabaseMetaData md = conn.getMetaData() ;
>              
> System.out.println(md.getDatabaseProductVersion());
>              System.out.println(md.getDatabaseProductName());
>              ps1 = conn.prepareStatement("CREATE TABLE TAB1(COL1 INT NOT NULL)");
>              ps1.executeUpdate();
>         	 System.out.println("done creating  table");
>              conn.commit ();
>          } catch (SQLException x)
>          {
>              System.out.println ("table already exists");
>          }                 
>         
>         XAConnection pc1 = ds.getXAConnection();
>         XAResource xar1 = pc1.getXAResource();
>         Xid xid1 = createXid(11);
>         xar1.start(xid1, XAResource.TMNOFLAGS);
>         Connection conn1 = pc1.getConnection();             
>         doSelect(conn1, 50);
> 		//doInsert(conn1);
>         conn1.close();
>         xar1.end(xid1, XAResource.TMSUCCESS);
>         int prp1 = xar1.prepare(xid1);
>         System.out.println("XAResource.XA_RDONLY" + 
> XAResource.XA_RDONLY);
>         System.out.println("XAResource.XA_OK" + 
> XAResource.XA_OK);
>         System.out.println("prp1 is: " + prp1);
>         // Commit transaction
>         if (prp1 == XAResource.XA_OK)
>            xar1.commit(xid1, false);
>         // Close physical connection
>         pc1.close();
>       }
>   
>     
>     private static void doSelect(Connection conn, int deptno) 
> throws SQLException 
>     {
>         Statement stmt = conn.createStatement();
>         ResultSet rset1 = stmt.executeQuery("select * from tab1");
>         while (rset1.next())
>         {
>         	System.out.println("==>: " + rset1.getString(1));
>         }
>         
>         stmt.close();
>         stmt = null;
>     }
> 	private static void doInsert(Connection conn) throws SQLException
> 	{
>         Statement stmt = conn.createStatement();
> 		stmt.executeUpdate("Insert into tab1 values(1)");
> 		stmt.close();
> 	}
>     
>     static Xid createXid(int bids) throws XAException {
>         byte[] gid = new byte[1];
>         gid[0] = (byte) 9;
>         byte[] bid = new byte[1];
>         bid[0] = (byte) bids;
>         byte[] gtrid = new byte[64];
>         byte[] bqual = new byte[64];
>         System.arraycopy(gid, 0, gtrid, 0, 1);
>         System.arraycopy(bid, 0, bqual, 0, 1);
>         Xid xid = new DB2Xid(0x1234, gtrid, bqual);
>         return xid;
>     }
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Commented: (DERBY-960) Client xa prepare returns XA_OK instead of XA_RDONLY for a read only transaction

Posted by "Kathey Marsden (JIRA)" <de...@db.apache.org>.
    [ http://issues.apache.org/jira/browse/DERBY-960?page=comments#action_12367188 ] 

Kathey Marsden commented on DERBY-960:
--------------------------------------

Suresh pointed out to me that this change caused the following new failures testing derbynetclientmats with 10.1 client and 10.2 server:

 (jdk15/IBM131/IBM142 client 10.1) derbynetclientmats: 
    derbynetclientmats/derbynetclientmats.fail:jdbcapi/xaSimplePositive.sql 
    derbynetclientmats/derbynetclientmats.fail:jdbcapi/xaStateTran.sql 
    both tests failed with following diff:
     
    > IJ ERROR: XA_RDONLY

I will port this fix to 10.1 which will resolve the failures on the latest version of 10.1 but it will continue to fail with older clients.    There was a discussion about whether to bump the DRDA maintenance version to make this work with older clients but the consensus was that anyone using XA will need both the client and server changes.
(see earlier comments in this issue).




> Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction
> ---------------------------------------------------------------------------------
>
>          Key: DERBY-960
>          URL: http://issues.apache.org/jira/browse/DERBY-960
>      Project: Derby
>         Type: Bug
>   Components: Network Client
>     Versions: 10.1.2.3, 10.1.3.0, 10.2.0.0, 10.1.2.2
>     Reporter: Kathey Marsden
>     Assignee: Kathey Marsden
>      Fix For: 10.2.0.0, 10.1.3.0, 10.1.2.3
>  Attachments: ReadOnlyTran.zip, derby960_preview.diff
>
> Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction
> The code below checks the return value of XaResource.prepare to decide whether to commit the transaction.   The prepare return value is XA_OK ( 0)  for client when it should be XA_RDONLY(3)
> D>java ReadOnlyTran derbycli
> 10.2.0.0 alpha
> Apache Derby
> Apache Derby Network Client JDBC Driver
> table already exists
> ==>: 1
> XAResource.XA_RDONLY3
> XAResource.XA_OK0
> prp1 is: 0
> Exception in thread "main" org.apache.derby.client.am.XaException: XAER_NOTA : Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.throwXAException(NetXAResource.java:728)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:216)
>         at ReadOnlyTran.main(ReadOnlyTran.java:94)
> Caused by: org.apache.derby.client.am.SqlException: Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.xaRetValErrorAccumSQL(NetXAResource.java:976)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:204)
>         ... 1 more
> D>
> import java.sql.Connection;
> import java.sql.DatabaseMetaData;
> import java.sql.PreparedStatement;
> import java.sql.ResultSet;
> 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 com.ibm.db2.jcc.DB2Xid;
> class ReadOnlyTran  
> {
>    
>     public static void main (String args [])throws Exception 
>     {
>     	//org.apache.derby.jdbc.ClientConnectionPoolDataSource ds = new org.apache.derby.jdbc.ClientConnectionPoolDataSource();
>     	org.apache.derby.jdbc.ClientXADataSource ds = new 
> 		org.apache.derby.jdbc.ClientXADataSource();
>     	//org.apache.derby.jdbc.EmbeddedXADataSource ds = new 
> 		//org.apache.derby.jdbc.EmbeddedXADataSource();
>     	Connection conn = null;
>     	ds.setDatabaseName("sample");
> 		ds.setTraceFile("trace.out");
>     	ds.setConnectionAttributes("create=true");
>          conn = ds.getConnection();
>         PreparedStatement ps1 = null;
>          try
>          {
>              DatabaseMetaData md = conn.getMetaData() ;
>              
> System.out.println(md.getDatabaseProductVersion());
>              System.out.println(md.getDatabaseProductName());
>              ps1 = conn.prepareStatement("CREATE TABLE TAB1(COL1 INT NOT NULL)");
>              ps1.executeUpdate();
>         	 System.out.println("done creating  table");
>              conn.commit ();
>          } catch (SQLException x)
>          {
>              System.out.println ("table already exists");
>          }                 
>         
>         XAConnection pc1 = ds.getXAConnection();
>         XAResource xar1 = pc1.getXAResource();
>         Xid xid1 = createXid(11);
>         xar1.start(xid1, XAResource.TMNOFLAGS);
>         Connection conn1 = pc1.getConnection();             
>         doSelect(conn1, 50);
> 		//doInsert(conn1);
>         conn1.close();
>         xar1.end(xid1, XAResource.TMSUCCESS);
>         int prp1 = xar1.prepare(xid1);
>         System.out.println("XAResource.XA_RDONLY" + 
> XAResource.XA_RDONLY);
>         System.out.println("XAResource.XA_OK" + 
> XAResource.XA_OK);
>         System.out.println("prp1 is: " + prp1);
>         // Commit transaction
>         if (prp1 == XAResource.XA_OK)
>            xar1.commit(xid1, false);
>         // Close physical connection
>         pc1.close();
>       }
>   
>     
>     private static void doSelect(Connection conn, int deptno) 
> throws SQLException 
>     {
>         Statement stmt = conn.createStatement();
>         ResultSet rset1 = stmt.executeQuery("select * from tab1");
>         while (rset1.next())
>         {
>         	System.out.println("==>: " + rset1.getString(1));
>         }
>         
>         stmt.close();
>         stmt = null;
>     }
> 	private static void doInsert(Connection conn) throws SQLException
> 	{
>         Statement stmt = conn.createStatement();
> 		stmt.executeUpdate("Insert into tab1 values(1)");
> 		stmt.close();
> 	}
>     
>     static Xid createXid(int bids) throws XAException {
>         byte[] gid = new byte[1];
>         gid[0] = (byte) 9;
>         byte[] bid = new byte[1];
>         bid[0] = (byte) bids;
>         byte[] gtrid = new byte[64];
>         byte[] bqual = new byte[64];
>         System.arraycopy(gid, 0, gtrid, 0, 1);
>         System.arraycopy(bid, 0, bqual, 0, 1);
>         Xid xid = new DB2Xid(0x1234, gtrid, bqual);
>         return xid;
>     }
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Closed: (DERBY-960) Client xa prepare returns XA_OK instead of XA_RDONLY for a read only transaction

Posted by "Kathey Marsden (JIRA)" <de...@db.apache.org>.
     [ http://issues.apache.org/jira/browse/DERBY-960?page=all ]
     
Kathey Marsden closed DERBY-960:
--------------------------------


> Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction
> ---------------------------------------------------------------------------------
>
>          Key: DERBY-960
>          URL: http://issues.apache.org/jira/browse/DERBY-960
>      Project: Derby
>         Type: Bug

>   Components: Network Client
>     Versions: 10.1.2.3, 10.1.3.0, 10.2.0.0, 10.1.2.2
>     Reporter: Kathey Marsden
>     Assignee: Kathey Marsden
>      Fix For: 10.2.0.0, 10.1.3.0, 10.1.2.3
>  Attachments: ReadOnlyTran.zip, derby960_preview.diff
>
> Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction
> The code below checks the return value of XaResource.prepare to decide whether to commit the transaction.   The prepare return value is XA_OK ( 0)  for client when it should be XA_RDONLY(3)
> D>java ReadOnlyTran derbycli
> 10.2.0.0 alpha
> Apache Derby
> Apache Derby Network Client JDBC Driver
> table already exists
> ==>: 1
> XAResource.XA_RDONLY3
> XAResource.XA_OK0
> prp1 is: 0
> Exception in thread "main" org.apache.derby.client.am.XaException: XAER_NOTA : Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.throwXAException(NetXAResource.java:728)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:216)
>         at ReadOnlyTran.main(ReadOnlyTran.java:94)
> Caused by: org.apache.derby.client.am.SqlException: Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.xaRetValErrorAccumSQL(NetXAResource.java:976)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:204)
>         ... 1 more
> D>
> import java.sql.Connection;
> import java.sql.DatabaseMetaData;
> import java.sql.PreparedStatement;
> import java.sql.ResultSet;
> 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 com.ibm.db2.jcc.DB2Xid;
> class ReadOnlyTran  
> {
>    
>     public static void main (String args [])throws Exception 
>     {
>     	//org.apache.derby.jdbc.ClientConnectionPoolDataSource ds = new org.apache.derby.jdbc.ClientConnectionPoolDataSource();
>     	org.apache.derby.jdbc.ClientXADataSource ds = new 
> 		org.apache.derby.jdbc.ClientXADataSource();
>     	//org.apache.derby.jdbc.EmbeddedXADataSource ds = new 
> 		//org.apache.derby.jdbc.EmbeddedXADataSource();
>     	Connection conn = null;
>     	ds.setDatabaseName("sample");
> 		ds.setTraceFile("trace.out");
>     	ds.setConnectionAttributes("create=true");
>          conn = ds.getConnection();
>         PreparedStatement ps1 = null;
>          try
>          {
>              DatabaseMetaData md = conn.getMetaData() ;
>              
> System.out.println(md.getDatabaseProductVersion());
>              System.out.println(md.getDatabaseProductName());
>              ps1 = conn.prepareStatement("CREATE TABLE TAB1(COL1 INT NOT NULL)");
>              ps1.executeUpdate();
>         	 System.out.println("done creating  table");
>              conn.commit ();
>          } catch (SQLException x)
>          {
>              System.out.println ("table already exists");
>          }                 
>         
>         XAConnection pc1 = ds.getXAConnection();
>         XAResource xar1 = pc1.getXAResource();
>         Xid xid1 = createXid(11);
>         xar1.start(xid1, XAResource.TMNOFLAGS);
>         Connection conn1 = pc1.getConnection();             
>         doSelect(conn1, 50);
> 		//doInsert(conn1);
>         conn1.close();
>         xar1.end(xid1, XAResource.TMSUCCESS);
>         int prp1 = xar1.prepare(xid1);
>         System.out.println("XAResource.XA_RDONLY" + 
> XAResource.XA_RDONLY);
>         System.out.println("XAResource.XA_OK" + 
> XAResource.XA_OK);
>         System.out.println("prp1 is: " + prp1);
>         // Commit transaction
>         if (prp1 == XAResource.XA_OK)
>            xar1.commit(xid1, false);
>         // Close physical connection
>         pc1.close();
>       }
>   
>     
>     private static void doSelect(Connection conn, int deptno) 
> throws SQLException 
>     {
>         Statement stmt = conn.createStatement();
>         ResultSet rset1 = stmt.executeQuery("select * from tab1");
>         while (rset1.next())
>         {
>         	System.out.println("==>: " + rset1.getString(1));
>         }
>         
>         stmt.close();
>         stmt = null;
>     }
> 	private static void doInsert(Connection conn) throws SQLException
> 	{
>         Statement stmt = conn.createStatement();
> 		stmt.executeUpdate("Insert into tab1 values(1)");
> 		stmt.close();
> 	}
>     
>     static Xid createXid(int bids) throws XAException {
>         byte[] gid = new byte[1];
>         gid[0] = (byte) 9;
>         byte[] bid = new byte[1];
>         bid[0] = (byte) bids;
>         byte[] gtrid = new byte[64];
>         byte[] bqual = new byte[64];
>         System.arraycopy(gid, 0, gtrid, 0, 1);
>         System.arraycopy(bid, 0, bqual, 0, 1);
>         Xid xid = new DB2Xid(0x1234, gtrid, bqual);
>         return xid;
>     }
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Commented: (DERBY-960) xa_commit results in XAER_NOTA on readonly transaction after xa_prepare returns XA_OK

Posted by "Kathey Marsden (JIRA)" <de...@db.apache.org>.
    [ http://issues.apache.org/jira/browse/DERBY-960?page=comments#action_12366153 ] 

Kathey Marsden commented on DERBY-960:
--------------------------------------

looking at this briefly I noticed the following.

1) Runs ok with EmbeddedXADAtaSource

2) The protocol flows from the client for prepare and commit with and without the insert are just the same, and  setting derby.drda.debug=true it looks like everything is going through the right path,  xid and flags are set correctly until we get this exception  on commit.  

javax.transaction.xa.XAException
	at org.apache.derby.jdbc.EmbedXAConnection.commit(EmbedXAConnection.java:425)
	at org.apache.derby.impl.drda.DRDAXAProtocol.commitXATransaction(DRDAXAProtocol.java:310)
	at org.apache.derby.impl.drda.DRDAXAProtocol.commitTransaction(DRDAXAProtocol.java:267)
	at org.apache.derby.impl.drda.DRDAXAProtocol.parseSYNCCTL(DRDAXAProtocol.java:139)
	at org.apache.derby.impl.drda.DRDAConnThread.processCommands(DRDAConnThread.java:906)
	at org.apache.derby.impl.drda.DRDAConnThread.run(DRDAConnThread.java:238)
Sending data
total memory: 2465792 free: 1340328 Sun Feb 12 22:25:07 PST 2006

Attaching repro and some traces in ReadOnlyTran.zip

ReadOnlyTran.java - repro for this issue

readonly.trace.out - client trace output with testcase and exception.
withinsert.trace.out - client trace outputwith insert added

nsreadonly.out -  Network Server output with derby.drda.debug=true with the testcase and exception.

nswithinsert.out - Network Server output with derby.drda.debug=true with the insert added 




> xa_commit results in  XAER_NOTA  on readonly transaction after xa_prepare returns XA_OK
> ---------------------------------------------------------------------------------------
>
>          Key: DERBY-960
>          URL: http://issues.apache.org/jira/browse/DERBY-960
>      Project: Derby
>         Type: Bug
>     Versions: 10.1.2.3, 10.1.3.0, 10.2.0.0, 10.1.2.2
>     Reporter: Kathey Marsden
>     Assignee: Kathey Marsden
>      Fix For: 10.2.0.0, 10.1.3.0, 10.1.2.3
>  Attachments: ReadOnlyTran.zip
>
> xa_commit results in  XAER_NOTA  on readonly transaction after xa_prepare returns XA_OK
> Two phase commit on a read only transaction causes the following error:
> Exception in thread "main" org.apache.derby.client.am.XaException: XAER_NOTA : Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.throwXAException(NetXAResource.java:728)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:216)
>         at ReadOnlyTran.main(ReadOnlyTran.java:78)
> Caused by: org.apache.derby.client.am.SqlException: Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.xaRetValErrorAccumSQL(NetXAResource.java:976)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:204)
>         ... 1 more
> The following program shows the problem:
> Uncommenting the insert will cause the test to pass.
> import java.sql.Connection;
> import java.sql.DatabaseMetaData;
> import java.sql.PreparedStatement;
> import java.sql.ResultSet;
> 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 com.ibm.db2.jcc.DB2Xid;
> class ReadOnlyTran  
> {
>    
>     public static void main (String args [])throws Exception 
>     {
>     	//org.apache.derby.jdbc.ClientConnectionPoolDataSource ds = new org.apache.derby.jdbc.ClientConnectionPoolDataSource();
>     	org.apache.derby.jdbc.ClientXADataSource ds = new 
> 		org.apache.derby.jdbc.ClientXADataSource();
>     	//org.apache.derby.jdbc.EmbeddedXADataSource ds = new 
> 		//org.apache.derby.jdbc.EmbeddedXADataSource();
>     	Connection conn = null;
>     	ds.setDatabaseName("sample");
> 		ds.setTraceFile("trace.out");
>     	ds.setConnectionAttributes("create=true");
>          conn = ds.getConnection();
>         PreparedStatement ps1 = null;
>          try
>          {
>              DatabaseMetaData md = conn.getMetaData() ;
>              
> System.out.println(md.getDatabaseProductVersion());
>              System.out.println(md.getDatabaseProductName());
>              ps1 = conn.prepareStatement("CREATE TABLE TAB1(COL1 INT NOT NULL)");
>              ps1.executeUpdate();
>         	 System.out.println("done creating  table");
>              conn.commit ();
>          } catch (SQLException x)
>          {
>              System.out.println ("table already exists");
>          }                 
>         
>         XAConnection pc1 = ds.getXAConnection();
>         XAResource xar1 = pc1.getXAResource();
>         Xid xid1 = createXid(11);
>         xar1.start(xid1, XAResource.TMNOFLAGS);
>         Connection conn1 = pc1.getConnection();             
>         doSelect(conn1, 50);
> 		//doInsert(conn1);
>         conn1.close();
>         xar1.end(xid1, XAResource.TMSUCCESS);
>         int prp1 = xar1.prepare(xid1);
>         System.out.println("XAResource.XA_RDONLY" + 
> XAResource.XA_RDONLY);
>         System.out.println("XAResource.XA_OK" + 
> XAResource.XA_OK);
>         System.out.println("prp1 is: " + prp1);
>         // Commit transaction
>         if (prp1 == XAResource.XA_OK)
>            xar1.commit(xid1, false);
>         // Close physical connection
>         pc1.close();
>       }
>   
>     
>     private static void doSelect(Connection conn, int deptno) 
> throws SQLException 
>     {
>         Statement stmt = conn.createStatement();
>         ResultSet rset1 = stmt.executeQuery("select * from tab1");
>         while (rset1.next())
>         {
>         	System.out.println("==>: " + rset1.getString(1));
>         }
>         
>         stmt.close();
>         stmt = null;
>     }
> 	private static void doInsert(Connection conn) throws SQLException
> 	{
>         Statement stmt = conn.createStatement();
> 		stmt.executeUpdate("Insert into tab1 values(1)");
> 		stmt.close();
> 	}
>     
>     static Xid createXid(int bids) throws XAException {
>         byte[] gid = new byte[1];
>         gid[0] = (byte) 9;
>         byte[] bid = new byte[1];
>         bid[0] = (byte) bids;
>         byte[] gtrid = new byte[64];
>         byte[] bqual = new byte[64];
>         System.arraycopy(gid, 0, gtrid, 0, 1);
>         System.arraycopy(bid, 0, bqual, 0, 1);
>         Xid xid = new DB2Xid(0x1234, gtrid, bqual);
>         return xid;
>     }
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


Re: [jira] Updated: (DERBY-960) Client xa prepare returns XA_OK instead of XA_RDONLY for a read only transaction

Posted by Bryan Pendleton <bp...@amberpoint.com>.
> Here is a preliminary patch for this issue.

Hi Kathey,

The server change looks great.

I don't understand the client change, though:

              // read the reply to the prepare
              rc = netAgent.netConnectionReply_.readXaPrepare(conn_);
-            if ((callInfo.xaRetVal_ != XARETVAL_XAOK) &&
+            if ((callInfo.xaRetVal_ != XARETVAL_XAOK && callInfo.xaRetVal_ != XA_RDONLY) &&
                      (callInfo.xaRetVal_ != XARETVAL_XARDONLY)) { // xaRetVal has possible error, format it
                  callInfo.xaFunction_ = XAFUNC_PREPARE;
                  rc = xaRetValErrorAccumSQL(callInfo, rc);

What is the difference between XARETVAL_XARDONLY and XA_RDONLY?

thanks,

bryan




[jira] Updated: (DERBY-960) Client xa prepare returns XA_OK instead of XA_RDONLY for a read only transaction

Posted by "Kathey Marsden (JIRA)" <de...@db.apache.org>.
     [ http://issues.apache.org/jira/browse/DERBY-960?page=all ]

Kathey Marsden updated DERBY-960:
---------------------------------

    Attachment: derby960_preview.diff

Here is a preliminary patch for this issue.
For Network Server
- Changed DRDAXAProtocol prepareXATransaction to return the return value of prepare in the SYNCCRD
The server was always returning XA_OK if prepare did not throw an error instead of passing the return value to the client.

For Network Client
- Changed NetXAResource()  prepare to handle XA_RDONLY returned from the server.  It was throwing an exception for any value returned from the server other than XA_OK.


ISSUE and QUESTION:
This patch is against the trunk, but the fix needs to go to 10.1

With this fix,  older clients working with newer servers will now throw an XAException when prepare returns XA_RDONLY because the client side fix is not in place.  This is potentially worse than the previous symptom of returning  XA_OK.  Should we bump the DRDA maintenance id and continue to return XA_OK with older clients, or just put this fix in place and require upgrade of client to the latest 10.1 to get the fix?




> Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction
> ---------------------------------------------------------------------------------
>
>          Key: DERBY-960
>          URL: http://issues.apache.org/jira/browse/DERBY-960
>      Project: Derby
>         Type: Bug
>   Components: Network Client
>     Versions: 10.1.2.3, 10.1.3.0, 10.2.0.0, 10.1.2.2
>     Reporter: Kathey Marsden
>     Assignee: Kathey Marsden
>      Fix For: 10.2.0.0, 10.1.3.0, 10.1.2.3
>  Attachments: ReadOnlyTran.zip, derby960_preview.diff
>
> Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction
> The code below checks the return value of XaResource.prepare to decide whether to commit the transaction.   The prepare return value is XA_OK ( 0)  for client when it should be XA_RDONLY(3)
> D>java ReadOnlyTran derbycli
> 10.2.0.0 alpha
> Apache Derby
> Apache Derby Network Client JDBC Driver
> table already exists
> ==>: 1
> XAResource.XA_RDONLY3
> XAResource.XA_OK0
> prp1 is: 0
> Exception in thread "main" org.apache.derby.client.am.XaException: XAER_NOTA : Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.throwXAException(NetXAResource.java:728)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:216)
>         at ReadOnlyTran.main(ReadOnlyTran.java:94)
> Caused by: org.apache.derby.client.am.SqlException: Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.xaRetValErrorAccumSQL(NetXAResource.java:976)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:204)
>         ... 1 more
> D>
> import java.sql.Connection;
> import java.sql.DatabaseMetaData;
> import java.sql.PreparedStatement;
> import java.sql.ResultSet;
> 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 com.ibm.db2.jcc.DB2Xid;
> class ReadOnlyTran  
> {
>    
>     public static void main (String args [])throws Exception 
>     {
>     	//org.apache.derby.jdbc.ClientConnectionPoolDataSource ds = new org.apache.derby.jdbc.ClientConnectionPoolDataSource();
>     	org.apache.derby.jdbc.ClientXADataSource ds = new 
> 		org.apache.derby.jdbc.ClientXADataSource();
>     	//org.apache.derby.jdbc.EmbeddedXADataSource ds = new 
> 		//org.apache.derby.jdbc.EmbeddedXADataSource();
>     	Connection conn = null;
>     	ds.setDatabaseName("sample");
> 		ds.setTraceFile("trace.out");
>     	ds.setConnectionAttributes("create=true");
>          conn = ds.getConnection();
>         PreparedStatement ps1 = null;
>          try
>          {
>              DatabaseMetaData md = conn.getMetaData() ;
>              
> System.out.println(md.getDatabaseProductVersion());
>              System.out.println(md.getDatabaseProductName());
>              ps1 = conn.prepareStatement("CREATE TABLE TAB1(COL1 INT NOT NULL)");
>              ps1.executeUpdate();
>         	 System.out.println("done creating  table");
>              conn.commit ();
>          } catch (SQLException x)
>          {
>              System.out.println ("table already exists");
>          }                 
>         
>         XAConnection pc1 = ds.getXAConnection();
>         XAResource xar1 = pc1.getXAResource();
>         Xid xid1 = createXid(11);
>         xar1.start(xid1, XAResource.TMNOFLAGS);
>         Connection conn1 = pc1.getConnection();             
>         doSelect(conn1, 50);
> 		//doInsert(conn1);
>         conn1.close();
>         xar1.end(xid1, XAResource.TMSUCCESS);
>         int prp1 = xar1.prepare(xid1);
>         System.out.println("XAResource.XA_RDONLY" + 
> XAResource.XA_RDONLY);
>         System.out.println("XAResource.XA_OK" + 
> XAResource.XA_OK);
>         System.out.println("prp1 is: " + prp1);
>         // Commit transaction
>         if (prp1 == XAResource.XA_OK)
>            xar1.commit(xid1, false);
>         // Close physical connection
>         pc1.close();
>       }
>   
>     
>     private static void doSelect(Connection conn, int deptno) 
> throws SQLException 
>     {
>         Statement stmt = conn.createStatement();
>         ResultSet rset1 = stmt.executeQuery("select * from tab1");
>         while (rset1.next())
>         {
>         	System.out.println("==>: " + rset1.getString(1));
>         }
>         
>         stmt.close();
>         stmt = null;
>     }
> 	private static void doInsert(Connection conn) throws SQLException
> 	{
>         Statement stmt = conn.createStatement();
> 		stmt.executeUpdate("Insert into tab1 values(1)");
> 		stmt.close();
> 	}
>     
>     static Xid createXid(int bids) throws XAException {
>         byte[] gid = new byte[1];
>         gid[0] = (byte) 9;
>         byte[] bid = new byte[1];
>         bid[0] = (byte) bids;
>         byte[] gtrid = new byte[64];
>         byte[] bqual = new byte[64];
>         System.arraycopy(gid, 0, gtrid, 0, 1);
>         System.arraycopy(bid, 0, bqual, 0, 1);
>         Xid xid = new DB2Xid(0x1234, gtrid, bqual);
>         return xid;
>     }
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Resolved: (DERBY-960) Client xa prepare returns XA_OK instead of XA_RDONLY for a read only transaction

Posted by "Kathey Marsden (JIRA)" <de...@db.apache.org>.
     [ http://issues.apache.org/jira/browse/DERBY-960?page=all ]
     
Kathey Marsden resolved DERBY-960:
----------------------------------

    Resolution: Fixed

Checked in fix to 10.1

Author: kmarsden
Date: Tue Feb 21 08:19:30 2006
New Revision: 379513

URL: http://svn.apache.org/viewcvs?rev=379513&view=rev


> Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction
> ---------------------------------------------------------------------------------
>
>          Key: DERBY-960
>          URL: http://issues.apache.org/jira/browse/DERBY-960
>      Project: Derby
>         Type: Bug
>   Components: Network Client
>     Versions: 10.1.2.3, 10.1.3.0, 10.2.0.0, 10.1.2.2
>     Reporter: Kathey Marsden
>     Assignee: Kathey Marsden
>      Fix For: 10.2.0.0, 10.1.3.0, 10.1.2.3
>  Attachments: ReadOnlyTran.zip, derby960_preview.diff
>
> Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction
> The code below checks the return value of XaResource.prepare to decide whether to commit the transaction.   The prepare return value is XA_OK ( 0)  for client when it should be XA_RDONLY(3)
> D>java ReadOnlyTran derbycli
> 10.2.0.0 alpha
> Apache Derby
> Apache Derby Network Client JDBC Driver
> table already exists
> ==>: 1
> XAResource.XA_RDONLY3
> XAResource.XA_OK0
> prp1 is: 0
> Exception in thread "main" org.apache.derby.client.am.XaException: XAER_NOTA : Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.throwXAException(NetXAResource.java:728)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:216)
>         at ReadOnlyTran.main(ReadOnlyTran.java:94)
> Caused by: org.apache.derby.client.am.SqlException: Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.xaRetValErrorAccumSQL(NetXAResource.java:976)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:204)
>         ... 1 more
> D>
> import java.sql.Connection;
> import java.sql.DatabaseMetaData;
> import java.sql.PreparedStatement;
> import java.sql.ResultSet;
> 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 com.ibm.db2.jcc.DB2Xid;
> class ReadOnlyTran  
> {
>    
>     public static void main (String args [])throws Exception 
>     {
>     	//org.apache.derby.jdbc.ClientConnectionPoolDataSource ds = new org.apache.derby.jdbc.ClientConnectionPoolDataSource();
>     	org.apache.derby.jdbc.ClientXADataSource ds = new 
> 		org.apache.derby.jdbc.ClientXADataSource();
>     	//org.apache.derby.jdbc.EmbeddedXADataSource ds = new 
> 		//org.apache.derby.jdbc.EmbeddedXADataSource();
>     	Connection conn = null;
>     	ds.setDatabaseName("sample");
> 		ds.setTraceFile("trace.out");
>     	ds.setConnectionAttributes("create=true");
>          conn = ds.getConnection();
>         PreparedStatement ps1 = null;
>          try
>          {
>              DatabaseMetaData md = conn.getMetaData() ;
>              
> System.out.println(md.getDatabaseProductVersion());
>              System.out.println(md.getDatabaseProductName());
>              ps1 = conn.prepareStatement("CREATE TABLE TAB1(COL1 INT NOT NULL)");
>              ps1.executeUpdate();
>         	 System.out.println("done creating  table");
>              conn.commit ();
>          } catch (SQLException x)
>          {
>              System.out.println ("table already exists");
>          }                 
>         
>         XAConnection pc1 = ds.getXAConnection();
>         XAResource xar1 = pc1.getXAResource();
>         Xid xid1 = createXid(11);
>         xar1.start(xid1, XAResource.TMNOFLAGS);
>         Connection conn1 = pc1.getConnection();             
>         doSelect(conn1, 50);
> 		//doInsert(conn1);
>         conn1.close();
>         xar1.end(xid1, XAResource.TMSUCCESS);
>         int prp1 = xar1.prepare(xid1);
>         System.out.println("XAResource.XA_RDONLY" + 
> XAResource.XA_RDONLY);
>         System.out.println("XAResource.XA_OK" + 
> XAResource.XA_OK);
>         System.out.println("prp1 is: " + prp1);
>         // Commit transaction
>         if (prp1 == XAResource.XA_OK)
>            xar1.commit(xid1, false);
>         // Close physical connection
>         pc1.close();
>       }
>   
>     
>     private static void doSelect(Connection conn, int deptno) 
> throws SQLException 
>     {
>         Statement stmt = conn.createStatement();
>         ResultSet rset1 = stmt.executeQuery("select * from tab1");
>         while (rset1.next())
>         {
>         	System.out.println("==>: " + rset1.getString(1));
>         }
>         
>         stmt.close();
>         stmt = null;
>     }
> 	private static void doInsert(Connection conn) throws SQLException
> 	{
>         Statement stmt = conn.createStatement();
> 		stmt.executeUpdate("Insert into tab1 values(1)");
> 		stmt.close();
> 	}
>     
>     static Xid createXid(int bids) throws XAException {
>         byte[] gid = new byte[1];
>         gid[0] = (byte) 9;
>         byte[] bid = new byte[1];
>         bid[0] = (byte) bids;
>         byte[] gtrid = new byte[64];
>         byte[] bqual = new byte[64];
>         System.arraycopy(gid, 0, gtrid, 0, 1);
>         System.arraycopy(bid, 0, bqual, 0, 1);
>         Xid xid = new DB2Xid(0x1234, gtrid, bqual);
>         return xid;
>     }
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Updated: (DERBY-960) xa_commit results in XAER_NOTA on readonly transaction after xa_prepare returns XA_OK

Posted by "Kathey Marsden (JIRA)" <de...@db.apache.org>.
     [ http://issues.apache.org/jira/browse/DERBY-960?page=all ]

Kathey Marsden updated DERBY-960:
---------------------------------

    Attachment: ReadOnlyTran.zip

Repro and some traces per previous comment.

> xa_commit results in  XAER_NOTA  on readonly transaction after xa_prepare returns XA_OK
> ---------------------------------------------------------------------------------------
>
>          Key: DERBY-960
>          URL: http://issues.apache.org/jira/browse/DERBY-960
>      Project: Derby
>         Type: Bug
>     Versions: 10.1.2.3, 10.1.3.0, 10.2.0.0, 10.1.2.2
>     Reporter: Kathey Marsden
>     Assignee: Kathey Marsden
>      Fix For: 10.2.0.0, 10.1.3.0, 10.1.2.3
>  Attachments: ReadOnlyTran.zip
>
> xa_commit results in  XAER_NOTA  on readonly transaction after xa_prepare returns XA_OK
> Two phase commit on a read only transaction causes the following error:
> Exception in thread "main" org.apache.derby.client.am.XaException: XAER_NOTA : Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.throwXAException(NetXAResource.java:728)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:216)
>         at ReadOnlyTran.main(ReadOnlyTran.java:78)
> Caused by: org.apache.derby.client.am.SqlException: Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.xaRetValErrorAccumSQL(NetXAResource.java:976)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:204)
>         ... 1 more
> The following program shows the problem:
> Uncommenting the insert will cause the test to pass.
> import java.sql.Connection;
> import java.sql.DatabaseMetaData;
> import java.sql.PreparedStatement;
> import java.sql.ResultSet;
> 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 com.ibm.db2.jcc.DB2Xid;
> class ReadOnlyTran  
> {
>    
>     public static void main (String args [])throws Exception 
>     {
>     	//org.apache.derby.jdbc.ClientConnectionPoolDataSource ds = new org.apache.derby.jdbc.ClientConnectionPoolDataSource();
>     	org.apache.derby.jdbc.ClientXADataSource ds = new 
> 		org.apache.derby.jdbc.ClientXADataSource();
>     	//org.apache.derby.jdbc.EmbeddedXADataSource ds = new 
> 		//org.apache.derby.jdbc.EmbeddedXADataSource();
>     	Connection conn = null;
>     	ds.setDatabaseName("sample");
> 		ds.setTraceFile("trace.out");
>     	ds.setConnectionAttributes("create=true");
>          conn = ds.getConnection();
>         PreparedStatement ps1 = null;
>          try
>          {
>              DatabaseMetaData md = conn.getMetaData() ;
>              
> System.out.println(md.getDatabaseProductVersion());
>              System.out.println(md.getDatabaseProductName());
>              ps1 = conn.prepareStatement("CREATE TABLE TAB1(COL1 INT NOT NULL)");
>              ps1.executeUpdate();
>         	 System.out.println("done creating  table");
>              conn.commit ();
>          } catch (SQLException x)
>          {
>              System.out.println ("table already exists");
>          }                 
>         
>         XAConnection pc1 = ds.getXAConnection();
>         XAResource xar1 = pc1.getXAResource();
>         Xid xid1 = createXid(11);
>         xar1.start(xid1, XAResource.TMNOFLAGS);
>         Connection conn1 = pc1.getConnection();             
>         doSelect(conn1, 50);
> 		//doInsert(conn1);
>         conn1.close();
>         xar1.end(xid1, XAResource.TMSUCCESS);
>         int prp1 = xar1.prepare(xid1);
>         System.out.println("XAResource.XA_RDONLY" + 
> XAResource.XA_RDONLY);
>         System.out.println("XAResource.XA_OK" + 
> XAResource.XA_OK);
>         System.out.println("prp1 is: " + prp1);
>         // Commit transaction
>         if (prp1 == XAResource.XA_OK)
>            xar1.commit(xid1, false);
>         // Close physical connection
>         pc1.close();
>       }
>   
>     
>     private static void doSelect(Connection conn, int deptno) 
> throws SQLException 
>     {
>         Statement stmt = conn.createStatement();
>         ResultSet rset1 = stmt.executeQuery("select * from tab1");
>         while (rset1.next())
>         {
>         	System.out.println("==>: " + rset1.getString(1));
>         }
>         
>         stmt.close();
>         stmt = null;
>     }
> 	private static void doInsert(Connection conn) throws SQLException
> 	{
>         Statement stmt = conn.createStatement();
> 		stmt.executeUpdate("Insert into tab1 values(1)");
> 		stmt.close();
> 	}
>     
>     static Xid createXid(int bids) throws XAException {
>         byte[] gid = new byte[1];
>         gid[0] = (byte) 9;
>         byte[] bid = new byte[1];
>         bid[0] = (byte) bids;
>         byte[] gtrid = new byte[64];
>         byte[] bqual = new byte[64];
>         System.arraycopy(gid, 0, gtrid, 0, 1);
>         System.arraycopy(bid, 0, bqual, 0, 1);
>         Xid xid = new DB2Xid(0x1234, gtrid, bqual);
>         return xid;
>     }
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Updated: (DERBY-960) Client xa prepare returns XA_OK instead of XA_RDONLY for a read only transaction

Posted by "Kathey Marsden (JIRA)" <de...@db.apache.org>.
     [ http://issues.apache.org/jira/browse/DERBY-960?page=all ]

Kathey Marsden updated DERBY-960:
---------------------------------

    Attachment:     (was: derby960_preview.diff)

> Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction
> ---------------------------------------------------------------------------------
>
>          Key: DERBY-960
>          URL: http://issues.apache.org/jira/browse/DERBY-960
>      Project: Derby
>         Type: Bug
>   Components: Network Client
>     Versions: 10.1.2.3, 10.1.3.0, 10.2.0.0, 10.1.2.2
>     Reporter: Kathey Marsden
>     Assignee: Kathey Marsden
>      Fix For: 10.2.0.0, 10.1.3.0, 10.1.2.3
>  Attachments: ReadOnlyTran.zip
>
> Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction
> The code below checks the return value of XaResource.prepare to decide whether to commit the transaction.   The prepare return value is XA_OK ( 0)  for client when it should be XA_RDONLY(3)
> D>java ReadOnlyTran derbycli
> 10.2.0.0 alpha
> Apache Derby
> Apache Derby Network Client JDBC Driver
> table already exists
> ==>: 1
> XAResource.XA_RDONLY3
> XAResource.XA_OK0
> prp1 is: 0
> Exception in thread "main" org.apache.derby.client.am.XaException: XAER_NOTA : Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.throwXAException(NetXAResource.java:728)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:216)
>         at ReadOnlyTran.main(ReadOnlyTran.java:94)
> Caused by: org.apache.derby.client.am.SqlException: Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.xaRetValErrorAccumSQL(NetXAResource.java:976)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:204)
>         ... 1 more
> D>
> import java.sql.Connection;
> import java.sql.DatabaseMetaData;
> import java.sql.PreparedStatement;
> import java.sql.ResultSet;
> 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 com.ibm.db2.jcc.DB2Xid;
> class ReadOnlyTran  
> {
>    
>     public static void main (String args [])throws Exception 
>     {
>     	//org.apache.derby.jdbc.ClientConnectionPoolDataSource ds = new org.apache.derby.jdbc.ClientConnectionPoolDataSource();
>     	org.apache.derby.jdbc.ClientXADataSource ds = new 
> 		org.apache.derby.jdbc.ClientXADataSource();
>     	//org.apache.derby.jdbc.EmbeddedXADataSource ds = new 
> 		//org.apache.derby.jdbc.EmbeddedXADataSource();
>     	Connection conn = null;
>     	ds.setDatabaseName("sample");
> 		ds.setTraceFile("trace.out");
>     	ds.setConnectionAttributes("create=true");
>          conn = ds.getConnection();
>         PreparedStatement ps1 = null;
>          try
>          {
>              DatabaseMetaData md = conn.getMetaData() ;
>              
> System.out.println(md.getDatabaseProductVersion());
>              System.out.println(md.getDatabaseProductName());
>              ps1 = conn.prepareStatement("CREATE TABLE TAB1(COL1 INT NOT NULL)");
>              ps1.executeUpdate();
>         	 System.out.println("done creating  table");
>              conn.commit ();
>          } catch (SQLException x)
>          {
>              System.out.println ("table already exists");
>          }                 
>         
>         XAConnection pc1 = ds.getXAConnection();
>         XAResource xar1 = pc1.getXAResource();
>         Xid xid1 = createXid(11);
>         xar1.start(xid1, XAResource.TMNOFLAGS);
>         Connection conn1 = pc1.getConnection();             
>         doSelect(conn1, 50);
> 		//doInsert(conn1);
>         conn1.close();
>         xar1.end(xid1, XAResource.TMSUCCESS);
>         int prp1 = xar1.prepare(xid1);
>         System.out.println("XAResource.XA_RDONLY" + 
> XAResource.XA_RDONLY);
>         System.out.println("XAResource.XA_OK" + 
> XAResource.XA_OK);
>         System.out.println("prp1 is: " + prp1);
>         // Commit transaction
>         if (prp1 == XAResource.XA_OK)
>            xar1.commit(xid1, false);
>         // Close physical connection
>         pc1.close();
>       }
>   
>     
>     private static void doSelect(Connection conn, int deptno) 
> throws SQLException 
>     {
>         Statement stmt = conn.createStatement();
>         ResultSet rset1 = stmt.executeQuery("select * from tab1");
>         while (rset1.next())
>         {
>         	System.out.println("==>: " + rset1.getString(1));
>         }
>         
>         stmt.close();
>         stmt = null;
>     }
> 	private static void doInsert(Connection conn) throws SQLException
> 	{
>         Statement stmt = conn.createStatement();
> 		stmt.executeUpdate("Insert into tab1 values(1)");
> 		stmt.close();
> 	}
>     
>     static Xid createXid(int bids) throws XAException {
>         byte[] gid = new byte[1];
>         gid[0] = (byte) 9;
>         byte[] bid = new byte[1];
>         bid[0] = (byte) bids;
>         byte[] gtrid = new byte[64];
>         byte[] bqual = new byte[64];
>         System.arraycopy(gid, 0, gtrid, 0, 1);
>         System.arraycopy(bid, 0, bqual, 0, 1);
>         Xid xid = new DB2Xid(0x1234, gtrid, bqual);
>         return xid;
>     }
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Commented: (DERBY-960) Client xa prepare returns XA_OK instead of XA_RDONLY for a read only transaction

Posted by "Bryan Pendleton (JIRA)" <de...@db.apache.org>.
    [ http://issues.apache.org/jira/browse/DERBY-960?page=comments#action_12366524 ] 

Bryan Pendleton commented on DERBY-960:
---------------------------------------

>  Should we bump the DRDA maintenance id and continue to return XA_OK with older clients, 
> or just put this fix in place and require upgrade of client to the latest 10.1 to get the fix?

I think we should require clients to upgrade. If I'm understanding this issue correctly, continuing to return XA_OK for a prepare of a read-only transaction is of little value to the client, because if they then proceed to try to commit that prepared-read-only branch of the global transaction, they'll get an exception from the commit, right?

So it seems like the client really needs to know the correct information, thus we need to just fix it in both places and ask users to get the fix.


> Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction
> ---------------------------------------------------------------------------------
>
>          Key: DERBY-960
>          URL: http://issues.apache.org/jira/browse/DERBY-960
>      Project: Derby
>         Type: Bug
>   Components: Network Client
>     Versions: 10.1.2.3, 10.1.3.0, 10.2.0.0, 10.1.2.2
>     Reporter: Kathey Marsden
>     Assignee: Kathey Marsden
>      Fix For: 10.2.0.0, 10.1.3.0, 10.1.2.3
>  Attachments: ReadOnlyTran.zip, derby960_preview.diff
>
> Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction
> The code below checks the return value of XaResource.prepare to decide whether to commit the transaction.   The prepare return value is XA_OK ( 0)  for client when it should be XA_RDONLY(3)
> D>java ReadOnlyTran derbycli
> 10.2.0.0 alpha
> Apache Derby
> Apache Derby Network Client JDBC Driver
> table already exists
> ==>: 1
> XAResource.XA_RDONLY3
> XAResource.XA_OK0
> prp1 is: 0
> Exception in thread "main" org.apache.derby.client.am.XaException: XAER_NOTA : Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.throwXAException(NetXAResource.java:728)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:216)
>         at ReadOnlyTran.main(ReadOnlyTran.java:94)
> Caused by: org.apache.derby.client.am.SqlException: Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.xaRetValErrorAccumSQL(NetXAResource.java:976)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:204)
>         ... 1 more
> D>
> import java.sql.Connection;
> import java.sql.DatabaseMetaData;
> import java.sql.PreparedStatement;
> import java.sql.ResultSet;
> 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 com.ibm.db2.jcc.DB2Xid;
> class ReadOnlyTran  
> {
>    
>     public static void main (String args [])throws Exception 
>     {
>     	//org.apache.derby.jdbc.ClientConnectionPoolDataSource ds = new org.apache.derby.jdbc.ClientConnectionPoolDataSource();
>     	org.apache.derby.jdbc.ClientXADataSource ds = new 
> 		org.apache.derby.jdbc.ClientXADataSource();
>     	//org.apache.derby.jdbc.EmbeddedXADataSource ds = new 
> 		//org.apache.derby.jdbc.EmbeddedXADataSource();
>     	Connection conn = null;
>     	ds.setDatabaseName("sample");
> 		ds.setTraceFile("trace.out");
>     	ds.setConnectionAttributes("create=true");
>          conn = ds.getConnection();
>         PreparedStatement ps1 = null;
>          try
>          {
>              DatabaseMetaData md = conn.getMetaData() ;
>              
> System.out.println(md.getDatabaseProductVersion());
>              System.out.println(md.getDatabaseProductName());
>              ps1 = conn.prepareStatement("CREATE TABLE TAB1(COL1 INT NOT NULL)");
>              ps1.executeUpdate();
>         	 System.out.println("done creating  table");
>              conn.commit ();
>          } catch (SQLException x)
>          {
>              System.out.println ("table already exists");
>          }                 
>         
>         XAConnection pc1 = ds.getXAConnection();
>         XAResource xar1 = pc1.getXAResource();
>         Xid xid1 = createXid(11);
>         xar1.start(xid1, XAResource.TMNOFLAGS);
>         Connection conn1 = pc1.getConnection();             
>         doSelect(conn1, 50);
> 		//doInsert(conn1);
>         conn1.close();
>         xar1.end(xid1, XAResource.TMSUCCESS);
>         int prp1 = xar1.prepare(xid1);
>         System.out.println("XAResource.XA_RDONLY" + 
> XAResource.XA_RDONLY);
>         System.out.println("XAResource.XA_OK" + 
> XAResource.XA_OK);
>         System.out.println("prp1 is: " + prp1);
>         // Commit transaction
>         if (prp1 == XAResource.XA_OK)
>            xar1.commit(xid1, false);
>         // Close physical connection
>         pc1.close();
>       }
>   
>     
>     private static void doSelect(Connection conn, int deptno) 
> throws SQLException 
>     {
>         Statement stmt = conn.createStatement();
>         ResultSet rset1 = stmt.executeQuery("select * from tab1");
>         while (rset1.next())
>         {
>         	System.out.println("==>: " + rset1.getString(1));
>         }
>         
>         stmt.close();
>         stmt = null;
>     }
> 	private static void doInsert(Connection conn) throws SQLException
> 	{
>         Statement stmt = conn.createStatement();
> 		stmt.executeUpdate("Insert into tab1 values(1)");
> 		stmt.close();
> 	}
>     
>     static Xid createXid(int bids) throws XAException {
>         byte[] gid = new byte[1];
>         gid[0] = (byte) 9;
>         byte[] bid = new byte[1];
>         bid[0] = (byte) bids;
>         byte[] gtrid = new byte[64];
>         byte[] bqual = new byte[64];
>         System.arraycopy(gid, 0, gtrid, 0, 1);
>         System.arraycopy(bid, 0, bqual, 0, 1);
>         Xid xid = new DB2Xid(0x1234, gtrid, bqual);
>         return xid;
>     }
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Updated: (DERBY-960) Client xa prepare returns XA_OK instead of XA_RDONLY for a read only transaction

Posted by "Kathey Marsden (JIRA)" <de...@db.apache.org>.
     [ http://issues.apache.org/jira/browse/DERBY-960?page=all ]

Kathey Marsden updated DERBY-960:
---------------------------------

    Attachment: derby960_preview.diff

Attaching a new diff. The first one had some residual cruft in it that was not needed.
The relevant client change is this:

--- java/client/org/apache/derby/client/net/NetXAResource.java  (revision 377480)
+++ java/client/org/apache/derby/client/net/NetXAResource.java  (working copy)
@@ -413,7 +413,7 @@
         } finally {
             conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending calli
nfo
         }
-        if (rc != XAResource.XA_OK) {
+        if ((rc != XAResource.XA_OK ) && (rc != XAResource.XA_RDONLY)) {
             throwXAException(rc, false);
         }
         if (conn_.agent_.loggingEnabled()) {


Perhaps the backward compatibility issue is not really as much of an issue as I first thought. 
With just the server fix  an unpatched client, the repro for this bug actually passes, but the read only case in xaSimplePositive  prints an  IJ ERROR: XA_RDONLY on the prepare.  I don't understand the difference in the two cases.


Regardless, I am a little conflicted about bumping the DRDA maintenance version and putting code in Network Server to continue returning the wrong return value, just because the client can't handle it.

Below is the case in xaSimplePositive that fails with an  unpatched cient and a patched server.
The IJ ERROR: XA_RDONLY does not occur  with both unpatched client and server and does not occur with the full patch.

The case looks just the same, xa_prepare on a read only transaction, so I am not sure what
xa_start xa_noflags 3;
ij(XA)> select * from APP.global_xactTable where gxid is not null order by gxid;
GXID |STATUS |READ& |USERNAME |TYPE
-----
(3 |IDLE |NULL |SKU |UserTransaction
ij(XA)> select * from APP.foo;
A
-----
0
1
3
ij(XA)> xa_end xa_success 3;
ij(XA)> xa_prepare 3;
IJ ERROR: XA_RDONLY
ij(XA)> -- should fail with XA_NOTA because we prepared a read only transaction
xa_commit xa_1Phase 3;
IJ ERROR: XAER_NOTA

So what do you think, do we bump the DRDA id for this or no?   I am ready to vote no as I think really anyone using client xa is just really going to need the client fix anyway.




> Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction
> ---------------------------------------------------------------------------------
>
>          Key: DERBY-960
>          URL: http://issues.apache.org/jira/browse/DERBY-960
>      Project: Derby
>         Type: Bug
>   Components: Network Client
>     Versions: 10.1.2.3, 10.1.3.0, 10.2.0.0, 10.1.2.2
>     Reporter: Kathey Marsden
>     Assignee: Kathey Marsden
>      Fix For: 10.2.0.0, 10.1.3.0, 10.1.2.3
>  Attachments: ReadOnlyTran.zip, derby960_preview.diff
>
> Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction
> The code below checks the return value of XaResource.prepare to decide whether to commit the transaction.   The prepare return value is XA_OK ( 0)  for client when it should be XA_RDONLY(3)
> D>java ReadOnlyTran derbycli
> 10.2.0.0 alpha
> Apache Derby
> Apache Derby Network Client JDBC Driver
> table already exists
> ==>: 1
> XAResource.XA_RDONLY3
> XAResource.XA_OK0
> prp1 is: 0
> Exception in thread "main" org.apache.derby.client.am.XaException: XAER_NOTA : Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.throwXAException(NetXAResource.java:728)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:216)
>         at ReadOnlyTran.main(ReadOnlyTran.java:94)
> Caused by: org.apache.derby.client.am.SqlException: Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.xaRetValErrorAccumSQL(NetXAResource.java:976)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:204)
>         ... 1 more
> D>
> import java.sql.Connection;
> import java.sql.DatabaseMetaData;
> import java.sql.PreparedStatement;
> import java.sql.ResultSet;
> 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 com.ibm.db2.jcc.DB2Xid;
> class ReadOnlyTran  
> {
>    
>     public static void main (String args [])throws Exception 
>     {
>     	//org.apache.derby.jdbc.ClientConnectionPoolDataSource ds = new org.apache.derby.jdbc.ClientConnectionPoolDataSource();
>     	org.apache.derby.jdbc.ClientXADataSource ds = new 
> 		org.apache.derby.jdbc.ClientXADataSource();
>     	//org.apache.derby.jdbc.EmbeddedXADataSource ds = new 
> 		//org.apache.derby.jdbc.EmbeddedXADataSource();
>     	Connection conn = null;
>     	ds.setDatabaseName("sample");
> 		ds.setTraceFile("trace.out");
>     	ds.setConnectionAttributes("create=true");
>          conn = ds.getConnection();
>         PreparedStatement ps1 = null;
>          try
>          {
>              DatabaseMetaData md = conn.getMetaData() ;
>              
> System.out.println(md.getDatabaseProductVersion());
>              System.out.println(md.getDatabaseProductName());
>              ps1 = conn.prepareStatement("CREATE TABLE TAB1(COL1 INT NOT NULL)");
>              ps1.executeUpdate();
>         	 System.out.println("done creating  table");
>              conn.commit ();
>          } catch (SQLException x)
>          {
>              System.out.println ("table already exists");
>          }                 
>         
>         XAConnection pc1 = ds.getXAConnection();
>         XAResource xar1 = pc1.getXAResource();
>         Xid xid1 = createXid(11);
>         xar1.start(xid1, XAResource.TMNOFLAGS);
>         Connection conn1 = pc1.getConnection();             
>         doSelect(conn1, 50);
> 		//doInsert(conn1);
>         conn1.close();
>         xar1.end(xid1, XAResource.TMSUCCESS);
>         int prp1 = xar1.prepare(xid1);
>         System.out.println("XAResource.XA_RDONLY" + 
> XAResource.XA_RDONLY);
>         System.out.println("XAResource.XA_OK" + 
> XAResource.XA_OK);
>         System.out.println("prp1 is: " + prp1);
>         // Commit transaction
>         if (prp1 == XAResource.XA_OK)
>            xar1.commit(xid1, false);
>         // Close physical connection
>         pc1.close();
>       }
>   
>     
>     private static void doSelect(Connection conn, int deptno) 
> throws SQLException 
>     {
>         Statement stmt = conn.createStatement();
>         ResultSet rset1 = stmt.executeQuery("select * from tab1");
>         while (rset1.next())
>         {
>         	System.out.println("==>: " + rset1.getString(1));
>         }
>         
>         stmt.close();
>         stmt = null;
>     }
> 	private static void doInsert(Connection conn) throws SQLException
> 	{
>         Statement stmt = conn.createStatement();
> 		stmt.executeUpdate("Insert into tab1 values(1)");
> 		stmt.close();
> 	}
>     
>     static Xid createXid(int bids) throws XAException {
>         byte[] gid = new byte[1];
>         gid[0] = (byte) 9;
>         byte[] bid = new byte[1];
>         bid[0] = (byte) bids;
>         byte[] gtrid = new byte[64];
>         byte[] bqual = new byte[64];
>         System.arraycopy(gid, 0, gtrid, 0, 1);
>         System.arraycopy(bid, 0, bqual, 0, 1);
>         Xid xid = new DB2Xid(0x1234, gtrid, bqual);
>         return xid;
>     }
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Updated: (DERBY-960) xa_commit results in XAER_NOTA on readonly transaction after xa_prepare returns XA_OK

Posted by "Kathey Marsden (JIRA)" <de...@db.apache.org>.
     [ http://issues.apache.org/jira/browse/DERBY-960?page=all ]

Kathey Marsden updated DERBY-960:
---------------------------------

    Component: Network Client

> xa_commit results in  XAER_NOTA  on readonly transaction after xa_prepare returns XA_OK
> ---------------------------------------------------------------------------------------
>
>          Key: DERBY-960
>          URL: http://issues.apache.org/jira/browse/DERBY-960
>      Project: Derby
>         Type: Bug
>   Components: Network Client
>     Versions: 10.1.2.3, 10.1.3.0, 10.2.0.0, 10.1.2.2
>     Reporter: Kathey Marsden
>     Assignee: Kathey Marsden
>      Fix For: 10.2.0.0, 10.1.3.0, 10.1.2.3
>  Attachments: ReadOnlyTran.zip
>
> xa_commit results in  XAER_NOTA  on readonly transaction after xa_prepare returns XA_OK
> Two phase commit on a read only transaction causes the following error:
> Exception in thread "main" org.apache.derby.client.am.XaException: XAER_NOTA : Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.throwXAException(NetXAResource.java:728)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:216)
>         at ReadOnlyTran.main(ReadOnlyTran.java:78)
> Caused by: org.apache.derby.client.am.SqlException: Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.xaRetValErrorAccumSQL(NetXAResource.java:976)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:204)
>         ... 1 more
> The following program shows the problem:
> Uncommenting the insert will cause the test to pass.
> import java.sql.Connection;
> import java.sql.DatabaseMetaData;
> import java.sql.PreparedStatement;
> import java.sql.ResultSet;
> 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 com.ibm.db2.jcc.DB2Xid;
> class ReadOnlyTran  
> {
>    
>     public static void main (String args [])throws Exception 
>     {
>     	//org.apache.derby.jdbc.ClientConnectionPoolDataSource ds = new org.apache.derby.jdbc.ClientConnectionPoolDataSource();
>     	org.apache.derby.jdbc.ClientXADataSource ds = new 
> 		org.apache.derby.jdbc.ClientXADataSource();
>     	//org.apache.derby.jdbc.EmbeddedXADataSource ds = new 
> 		//org.apache.derby.jdbc.EmbeddedXADataSource();
>     	Connection conn = null;
>     	ds.setDatabaseName("sample");
> 		ds.setTraceFile("trace.out");
>     	ds.setConnectionAttributes("create=true");
>          conn = ds.getConnection();
>         PreparedStatement ps1 = null;
>          try
>          {
>              DatabaseMetaData md = conn.getMetaData() ;
>              
> System.out.println(md.getDatabaseProductVersion());
>              System.out.println(md.getDatabaseProductName());
>              ps1 = conn.prepareStatement("CREATE TABLE TAB1(COL1 INT NOT NULL)");
>              ps1.executeUpdate();
>         	 System.out.println("done creating  table");
>              conn.commit ();
>          } catch (SQLException x)
>          {
>              System.out.println ("table already exists");
>          }                 
>         
>         XAConnection pc1 = ds.getXAConnection();
>         XAResource xar1 = pc1.getXAResource();
>         Xid xid1 = createXid(11);
>         xar1.start(xid1, XAResource.TMNOFLAGS);
>         Connection conn1 = pc1.getConnection();             
>         doSelect(conn1, 50);
> 		//doInsert(conn1);
>         conn1.close();
>         xar1.end(xid1, XAResource.TMSUCCESS);
>         int prp1 = xar1.prepare(xid1);
>         System.out.println("XAResource.XA_RDONLY" + 
> XAResource.XA_RDONLY);
>         System.out.println("XAResource.XA_OK" + 
> XAResource.XA_OK);
>         System.out.println("prp1 is: " + prp1);
>         // Commit transaction
>         if (prp1 == XAResource.XA_OK)
>            xar1.commit(xid1, false);
>         // Close physical connection
>         pc1.close();
>       }
>   
>     
>     private static void doSelect(Connection conn, int deptno) 
> throws SQLException 
>     {
>         Statement stmt = conn.createStatement();
>         ResultSet rset1 = stmt.executeQuery("select * from tab1");
>         while (rset1.next())
>         {
>         	System.out.println("==>: " + rset1.getString(1));
>         }
>         
>         stmt.close();
>         stmt = null;
>     }
> 	private static void doInsert(Connection conn) throws SQLException
> 	{
>         Statement stmt = conn.createStatement();
> 		stmt.executeUpdate("Insert into tab1 values(1)");
> 		stmt.close();
> 	}
>     
>     static Xid createXid(int bids) throws XAException {
>         byte[] gid = new byte[1];
>         gid[0] = (byte) 9;
>         byte[] bid = new byte[1];
>         bid[0] = (byte) bids;
>         byte[] gtrid = new byte[64];
>         byte[] bqual = new byte[64];
>         System.arraycopy(gid, 0, gtrid, 0, 1);
>         System.arraycopy(bid, 0, bqual, 0, 1);
>         Xid xid = new DB2Xid(0x1234, gtrid, bqual);
>         return xid;
>     }
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Commented: (DERBY-960) Client xa prepare returns XA_OK instead of XA_RDONLY for a read only transaction

Posted by "Kathey Marsden (JIRA)" <de...@db.apache.org>.
    [ http://issues.apache.org/jira/browse/DERBY-960?page=comments#action_12366843 ] 

Kathey Marsden commented on DERBY-960:
--------------------------------------

Checked this fix into 10.2
The test for this issue was checked in (accidentally) in patch2 of DERBY-435.
I will add an appropriate comment to that test.

Date: Fri Feb 17 11:44:47 2006
New Revision: 378613

URL: http://svn.apache.org/viewcvs?rev=378613&view=rev

Leaving this issue open for port to 10.1


> Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction
> ---------------------------------------------------------------------------------
>
>          Key: DERBY-960
>          URL: http://issues.apache.org/jira/browse/DERBY-960
>      Project: Derby
>         Type: Bug
>   Components: Network Client
>     Versions: 10.1.2.3, 10.1.3.0, 10.2.0.0, 10.1.2.2
>     Reporter: Kathey Marsden
>     Assignee: Kathey Marsden
>      Fix For: 10.2.0.0, 10.1.3.0, 10.1.2.3
>  Attachments: ReadOnlyTran.zip, derby960_preview.diff
>
> Client xa prepare returns XA_OK instead of  XA_RDONLY for a read only transaction
> The code below checks the return value of XaResource.prepare to decide whether to commit the transaction.   The prepare return value is XA_OK ( 0)  for client when it should be XA_RDONLY(3)
> D>java ReadOnlyTran derbycli
> 10.2.0.0 alpha
> Apache Derby
> Apache Derby Network Client JDBC Driver
> table already exists
> ==>: 1
> XAResource.XA_RDONLY3
> XAResource.XA_OK0
> prp1 is: 0
> Exception in thread "main" org.apache.derby.client.am.XaException: XAER_NOTA : Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.throwXAException(NetXAResource.java:728)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:216)
>         at ReadOnlyTran.main(ReadOnlyTran.java:94)
> Caused by: org.apache.derby.client.am.SqlException: Error executing a XAResource.commit(), Server returned XAER_NOTA
>         at org.apache.derby.client.net.NetXAResource.xaRetValErrorAccumSQL(NetXAResource.java:976)
>         at org.apache.derby.client.net.NetXAResource.commit(NetXAResource.java:204)
>         ... 1 more
> D>
> import java.sql.Connection;
> import java.sql.DatabaseMetaData;
> import java.sql.PreparedStatement;
> import java.sql.ResultSet;
> 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 com.ibm.db2.jcc.DB2Xid;
> class ReadOnlyTran  
> {
>    
>     public static void main (String args [])throws Exception 
>     {
>     	//org.apache.derby.jdbc.ClientConnectionPoolDataSource ds = new org.apache.derby.jdbc.ClientConnectionPoolDataSource();
>     	org.apache.derby.jdbc.ClientXADataSource ds = new 
> 		org.apache.derby.jdbc.ClientXADataSource();
>     	//org.apache.derby.jdbc.EmbeddedXADataSource ds = new 
> 		//org.apache.derby.jdbc.EmbeddedXADataSource();
>     	Connection conn = null;
>     	ds.setDatabaseName("sample");
> 		ds.setTraceFile("trace.out");
>     	ds.setConnectionAttributes("create=true");
>          conn = ds.getConnection();
>         PreparedStatement ps1 = null;
>          try
>          {
>              DatabaseMetaData md = conn.getMetaData() ;
>              
> System.out.println(md.getDatabaseProductVersion());
>              System.out.println(md.getDatabaseProductName());
>              ps1 = conn.prepareStatement("CREATE TABLE TAB1(COL1 INT NOT NULL)");
>              ps1.executeUpdate();
>         	 System.out.println("done creating  table");
>              conn.commit ();
>          } catch (SQLException x)
>          {
>              System.out.println ("table already exists");
>          }                 
>         
>         XAConnection pc1 = ds.getXAConnection();
>         XAResource xar1 = pc1.getXAResource();
>         Xid xid1 = createXid(11);
>         xar1.start(xid1, XAResource.TMNOFLAGS);
>         Connection conn1 = pc1.getConnection();             
>         doSelect(conn1, 50);
> 		//doInsert(conn1);
>         conn1.close();
>         xar1.end(xid1, XAResource.TMSUCCESS);
>         int prp1 = xar1.prepare(xid1);
>         System.out.println("XAResource.XA_RDONLY" + 
> XAResource.XA_RDONLY);
>         System.out.println("XAResource.XA_OK" + 
> XAResource.XA_OK);
>         System.out.println("prp1 is: " + prp1);
>         // Commit transaction
>         if (prp1 == XAResource.XA_OK)
>            xar1.commit(xid1, false);
>         // Close physical connection
>         pc1.close();
>       }
>   
>     
>     private static void doSelect(Connection conn, int deptno) 
> throws SQLException 
>     {
>         Statement stmt = conn.createStatement();
>         ResultSet rset1 = stmt.executeQuery("select * from tab1");
>         while (rset1.next())
>         {
>         	System.out.println("==>: " + rset1.getString(1));
>         }
>         
>         stmt.close();
>         stmt = null;
>     }
> 	private static void doInsert(Connection conn) throws SQLException
> 	{
>         Statement stmt = conn.createStatement();
> 		stmt.executeUpdate("Insert into tab1 values(1)");
> 		stmt.close();
> 	}
>     
>     static Xid createXid(int bids) throws XAException {
>         byte[] gid = new byte[1];
>         gid[0] = (byte) 9;
>         byte[] bid = new byte[1];
>         bid[0] = (byte) bids;
>         byte[] gtrid = new byte[64];
>         byte[] bqual = new byte[64];
>         System.arraycopy(gid, 0, gtrid, 0, 1);
>         System.arraycopy(bid, 0, bqual, 0, 1);
>         Xid xid = new DB2Xid(0x1234, gtrid, bqual);
>         return xid;
>     }
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira