use of org.apache.derbyTesting.functionTests.util.DeadlockWatchdog 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();
}
Aggregations