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