use of javax.sql.XAConnection in project derby by apache.
the class XATest method testSingleConnectionOnePhaseCommit.
/**
* A single connection and 1 phase commit.
*
* Original "SQL" from xaSimplePositive.sql <code>
* xa_connect ;
* xa_start xa_noflags 0;
* xa_getconnection;
* drop table foo;
* create table foo (a int);
* insert into foo values (0);
* select * from foo;
* run resource '/org/apache/derbyTesting/functionTests/tests/store/global_xactTable.view';
* select * from global_xactTable where gxid is not null order by gxid;
* xa_end xa_success 0;
* xa_commit xa_1phase 0;
*
* xa_datasource 'wombat' shutdown;
* </code>
*
* @throws SQLException
* @throws XAException
* @throws XAException
*/
public void testSingleConnectionOnePhaseCommit() throws SQLException, XAException {
XADataSource xads = J2EEDataSource.getXADataSource();
J2EEDataSource.setBeanProperty(xads, "databaseName", "wombat");
XAConnection xac = xads.getXAConnection();
XAResource xar = xac.getXAResource();
Xid xid = XATestUtil.getXid(0, 32, 46);
xar.start(xid, XAResource.TMNOFLAGS);
Connection conn = xac.getConnection();
assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, conn.getHoldability());
Statement s = conn.createStatement();
assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, s.getResultSetHoldability());
s.execute("create table foo (a int)");
s.executeUpdate("insert into foo values (0)");
ResultSet rs = s.executeQuery("select * from foo");
JDBC.assertDrainResults(rs, 1);
String[][] expectedRows = { { "(0", "ACTIVE", "false", "APP", "UserTransaction" } };
XATestUtil.checkXATransactionView(conn, expectedRows);
s.close();
xar.end(xid, XAResource.TMSUCCESS);
// 1 phase commit
xar.commit(xid, true);
conn.close();
xac.close();
}
use of javax.sql.XAConnection in project derby by apache.
the class XATest method testDerby6879.
/**
* DERBY-6879 Check that a XA transaction timeout while a cleanupOnError is
* being performed does not cause a Java level deadlock.
*
* The strategy is to cause a XA statement to wait for a period that is
* longer than the XA transaction timeout which will allow the timeout to
* cancel the XA transaction. That is accomplished by locking a table using
* a standard connection and then issuing a select on the same table using a
* XA connection. The select will wait for the required locks to be
* available up to the lock timeout. For the test to work correctly the XA
* transaction timeout must be less than the lock timeout.
*
* A dealock watchdog is used to detect the deadlock until the DERBY-6879
* issue is fixed.
*
* @throws SQLException
* @throws XAException
*/
public void testDerby6879() throws SQLException, XAException {
XADataSource xads = J2EEDataSource.getXADataSource();
J2EEDataSource.setBeanProperty(xads, "databaseName", "wombat");
Connection conn = J2EEDataSource.getConnectionPoolDataSource().getPooledConnection().getConnection();
conn.setAutoCommit(false);
Statement s = conn.createStatement();
s.execute("LOCK TABLE TABLT IN EXCLUSIVE MODE");
// Get a second connection and global xact
// and try to select causing lock timeout
XAConnection xaconn2 = xads.getXAConnection();
XAResource xar2 = xaconn2.getXAResource();
xar2.setTransactionTimeout(2);
Xid xid2 = XATestUtil.getXid(6879, 11, 51);
Connection conn2 = xaconn2.getConnection();
// Set to serializable so we get lock timeout
conn2.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
xar2.start(xid2, XAResource.TMNOFLAGS);
Statement s2 = conn2.createStatement();
assertGlobalXactCount(1);
DeadlockWatchdog wd = new DeadlockWatchdog(30 * 1000);
wd.start();
try {
ResultSet rs = s2.executeQuery("SELECT * FROM TABLT");
fail("Should have gotten lock timeout error: " + LOCKTIMEOUT);
} catch (SQLException se) {
assertSQLState(LOCKTIMEOUT, se);
}
wd.stop();
// xid2 should have already been rolled back so end should fail
try {
xar2.end(xid2, XAResource.TMSUCCESS);
fail("Should have gotten exception ending xid2");
} catch (XAException xae) {
assertTrue(xae.errorCode >= XAException.XAER_OUTSIDE || xae.errorCode <= XAException.XAER_ASYNC);
}
conn.commit();
conn.close();
conn2.close();
xaconn2.close();
}
use of javax.sql.XAConnection in project derby by apache.
the class XATest method testInterleavingTransactions.
/*
* Two interleaving transaction and prepare/commit prepare/rollback.
*
* (original test said two connections but only one connection was opened)
*
* <code> xa_datasource 'wombat'; xa_connect user 'sku' password 'testxa' ;
*
* xa_start xa_noflags 1; xa_getconnection; insert into APP.foo values (1);
* xa_end xa_suspend 1;
*
* xa_start xa_noflags 2; insert into APP.foo values (2); xa_end xa_suspend
* 2;
*
* xa_start xa_resume 1; insert into APP.foo values (3); xa_end xa_suspend
* 1;
*
* xa_start xa_resume 2; insert into APP.foo values (4); select * from
* APP.global_xactTable where gxid is not null order by gxid; -- this
* prepare won't work since transaction 1 has been suspended - XA_PROTO
* xa_prepare 1;
*
* select * from APP.global_xactTable where gxid is not null order by gxid;
* xa_end xa_success 2; -- this assumes a resume xa_end xa_success 1;
* xa_prepare 1; xa_prepare 2; -- both transactions should be prepared
* select * from APP.global_xactTable where gxid is not null order by gxid; --
* NOTE: The following call to "xa_recover xa_startrscan" is apt to --
* return the result set rows in reverse order when changes to -- the Derby
* engine affect the number of transactions that it takes -- to create a
* database. The transactions are stored in a hash table -- based on a
* global and local id, and when the number of transactions -- changes, the
* (internal) local id can change, which may lead to a -- change in the
* result set order. This order is determined by the -- JVM's hashing
* algorithm. Examples of changes to the engine that -- can affect this
* include ones that cause more commits or that -- change the amount of data
* being stored, such as changes to the -- metadata statements (which is
* what prompted this explanation in -- the first place). Ultimately, the
* problem is that there is no -- way to order the return values from
* "xa_recover" since it is an -- ij internal statement, not SQL...
* xa_recover xa_startrscan; xa_recover xa_noflags;
*
* xa_commit xa_2Phase 1; xa_rollback 2; -- check results xa_start
* xa_noflags 3; select * from APP.global_xactTable where gxid is not null
* order by gxid; select * from APP.foo; xa_end xa_success 3;
*
* xa_prepare 3; -- should fail with XA_NOTA because we prepared a read only
* transaction xa_commit xa_1Phase 3; disconnect; </code>
*/
public void testInterleavingTransactions() throws SQLException, XAException {
Statement preStatement = getConnection().createStatement();
preStatement.execute("create table fooInterleaving (a int)");
preStatement.execute("insert into fooInterleaving values (0)");
preStatement.close();
XADataSource xads = J2EEDataSource.getXADataSource();
XAConnection xac = xads.getXAConnection("sku", "testxa");
XAResource xar = xac.getXAResource();
Xid xid1 = XATestUtil.getXid(1, 93, 18);
Xid xid2 = XATestUtil.getXid(2, 45, 77);
xar.start(xid1, XAResource.TMNOFLAGS);
Connection conn = xac.getConnection();
Statement s = conn.createStatement();
s.executeUpdate("insert into APP.fooInterleaving values (1)");
xar.end(xid1, XAResource.TMSUSPEND);
xar.start(xid2, XAResource.TMNOFLAGS);
s.executeUpdate("insert into APP.fooInterleaving values (2)");
xar.end(xid2, XAResource.TMSUSPEND);
xar.start(xid1, XAResource.TMRESUME);
s.executeUpdate("insert into APP.fooInterleaving values (3)");
xar.end(xid1, XAResource.TMSUSPEND);
xar.start(xid2, XAResource.TMRESUME);
s.executeUpdate("insert into APP.fooInterleaving values (4)");
String[][] expectedRows = { { "(1", "ACTIVE", "false", "SKU", "UserTransaction" }, { "(2", "ACTIVE", "false", "SKU", "UserTransaction" } };
XATestUtil.checkXATransactionView(conn, expectedRows);
// transaction 1 has been suspended - XA_PROTO
try {
xar.prepare(xid1);
fail("FAIL - prepare on suspended transaction");
} catch (XAException e) {
if (e.errorCode != XAException.XAER_PROTO)
XATestUtil.dumpXAException("FAIL - prepare on suspended transaction", e);
}
// check it was not prepared
XATestUtil.checkXATransactionView(conn, expectedRows);
xar.end(xid2, XAResource.TMSUCCESS);
xar.end(xid1, XAResource.TMSUCCESS);
xar.prepare(xid1);
xar.prepare(xid2);
// both should be prepared.
expectedRows = new String[][] { { "(1", "PREPARED", "false", "SKU", "UserTransaction" }, { "(2", "PREPARED", "false", "SKU", "UserTransaction" } };
XATestUtil.checkXATransactionView(conn, expectedRows);
Xid[] recoveredStart = xar.recover(XAResource.TMSTARTRSCAN);
assertEquals(2, recoveredStart.length);
Xid[] recovered = xar.recover(XAResource.TMNOFLAGS);
assertEquals(0, recovered.length);
Xid[] recoveredEnd = xar.recover(XAResource.TMENDRSCAN);
assertEquals(0, recoveredEnd.length);
for (int i = 0; i < recoveredStart.length; i++) {
Xid xid = recoveredStart[i];
if (xid.getFormatId() == 1) {
// commit 1 with 2pc
xar.commit(xid, false);
} else if (xid.getFormatId() == 2) {
xar.rollback(xid);
} else {
fail("FAIL: unknown xact");
}
}
// check the results
Xid xid3 = XATestUtil.getXid(3, 2, 101);
xar.start(xid3, XAResource.TMNOFLAGS);
expectedRows = new String[][] { { "(3", "IDLE", "NULL", "SKU", "UserTransaction" } };
XATestUtil.checkXATransactionView(conn, expectedRows);
ResultSet rs = s.executeQuery("select * from APP.fooInterleaving");
expectedRows = new String[][] { { "0" }, { "1" }, { "3" } };
JDBC.assertFullResultSet(rs, expectedRows);
rs.close();
xar.end(xid3, XAResource.TMSUCCESS);
int pr = xar.prepare(xid3);
if (pr != XAResource.XA_RDONLY)
fail("FAIL - prepare on read only xact returned " + pr);
try {
xar.commit(xid3, true);
fail("FAIL - 2pc commit on read-only xact");
} catch (XAException e) {
if (e.errorCode != XAException.XAER_NOTA)
throw e;
}
s.close();
conn.close();
xac.close();
}
use of javax.sql.XAConnection in project derby by apache.
the class XATest method testDerby4310PreparedStatement.
/**
* This test checks the fix on DERBY-4310, for not repreparing PreparedStatements
* upon calling close() on them.
*/
public void testDerby4310PreparedStatement() throws SQLException, XAException {
XADataSource xads = J2EEDataSource.getXADataSource();
J2EEDataSource.setBeanProperty(xads, "databaseName", "wombat");
XAConnection xaconn = xads.getXAConnection();
XAResource xar = xaconn.getXAResource();
Xid xid = XATestUtil.getXid(1, 93, 18);
/* Create the table and insert some records into it. */
Connection conn = xaconn.getConnection();
Statement s = conn.createStatement();
s.executeUpdate("CREATE TABLE foo4310_PS (I INT)");
conn.createStatement().executeUpdate("insert into APP.foo4310_PS values (0)");
conn.createStatement().executeUpdate("insert into APP.foo4310_PS values (1)");
conn.createStatement().executeUpdate("insert into APP.foo4310_PS values (2)");
conn.commit();
/* Prepare and execute the statement to be tested */
PreparedStatement ps = conn.prepareStatement("SELECT * FROM APP.foo4310_PS");
ps.executeQuery().close();
/* Start and end a transaction on the XAResource object */
xar.start(xid, XAResource.TMNOFLAGS);
xar.end(xid, XAResource.TMSUCCESS);
/* Drop the table on a parallel, regular connection */
Connection conn2 = getConnection();
Statement s2 = conn2.createStatement();
s2.execute("DROP TABLE foo4310_PS");
conn2.commit();
conn2.close();
try {
/* Try to close the prepared statement. This would throw an exception
* before the fix, claiming that the table was not found. */
ps.close();
} finally {
/* Rollback the transaction and close the connections */
xar.rollback(xid);
conn.close();
xaconn.close();
}
}
use of javax.sql.XAConnection in project derby by apache.
the class XATransactionTest method testXAExceptionErrorCodeOnSQLExceptionDerby4141.
/**
* DERBY-4141 XAExceptions caused by SQLExceptions should have a
* non-zero errorCode. SESSION_SEVERITY or greater map to
* XAException.XAER_RMFAIL. Lesser exceptions map to XAException.XAER_RMERR
* @throws Exception
*/
public void testXAExceptionErrorCodeOnSQLExceptionDerby4141() throws Exception {
XADataSource xaDataSource = J2EEDataSource.getXADataSource();
XAConnection xaConn = xaDataSource.getXAConnection();
XAResource xaRes = xaConn.getXAResource();
Xid xid = createXid(123, 1);
// close the XAConnection so we get an SQLException on
// start();
xaConn.close();
try {
xaRes.start(xid, XAResource.TMNOFLAGS);
fail("Should have gotten an XAException. xaConn is closed.");
} catch (XAException xae) {
assertEquals(XAException.XAER_RMFAIL, xae.errorCode);
}
}
Aggregations