[ 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

Reply via email to