Search in sources :

Example 1 with DeadlockWatchdog

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();
}
Also used : DeadlockWatchdog(org.apache.derbyTesting.functionTests.util.DeadlockWatchdog) XADataSource(javax.sql.XADataSource) XAResource(javax.transaction.xa.XAResource) Xid(javax.transaction.xa.Xid) XAException(javax.transaction.xa.XAException) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) CallableStatement(java.sql.CallableStatement) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) ResultSet(java.sql.ResultSet) XAConnection(javax.sql.XAConnection)

Aggregations

CallableStatement (java.sql.CallableStatement)1 Connection (java.sql.Connection)1 PreparedStatement (java.sql.PreparedStatement)1 ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1 Statement (java.sql.Statement)1 XAConnection (javax.sql.XAConnection)1 XADataSource (javax.sql.XADataSource)1 XAException (javax.transaction.xa.XAException)1 XAResource (javax.transaction.xa.XAResource)1 Xid (javax.transaction.xa.Xid)1 DeadlockWatchdog (org.apache.derbyTesting.functionTests.util.DeadlockWatchdog)1