Search in sources :

Example 96 with XAConnection

use of javax.sql.XAConnection in project derby by apache.

the class XATransactionTest method testXATransactionTimeout.

/**
 * Tests the functionality of the XA transaction timeout.
 * <p>
 * It executes 66 global transactions during the test. Everyone
 * of them just inserts a row into XATT table. The rows inserted
 * by the transactions are different. Some of these transactions
 * are committed and some of them are left in different stages.
 * The stage of the transaction in which it is left is chosed
 * depending on division remainders.
 * </p>
 * <p>
 * After finishing these 1000 transactions a select statement is executed
 * on that table. However, if there are still some unfinished transactions
 * that were not aborted they will hold a lock on a XATT table until they
 * will get rolled back by the transaction timeout. The number of rows
 * in the XATT table is calculated. It is then compared with the excepted
 * number of rows (the transaction we know we have committed).
 * </p>
 * <p>
 * The call to xaRes.setTransactionTimeout(5) before the call
 * to xaRes.start() makes the transactions to be rolled back
 * due to timeout.
 * </p>
 */
public void testXATransactionTimeout() throws Exception {
    /* The number of statements to execute in timeout related test. */
    int timeoutStatementsToExecute = 66;
    /* Specifies the number of total executed statements per one
           commited statement in timeout related test. */
    int timeoutCommitEveryStatement = 3;
    /* Specifies the number of statements that should be commited
           during a timeout related test. */
    int timeoutStatementsCommitted = (timeoutStatementsToExecute + timeoutCommitEveryStatement - 1) / timeoutCommitEveryStatement;
    Statement stm = getConnection().createStatement();
    stm.execute("create table XATT (i int, text char(10))");
    XADataSource xaDataSource = J2EEDataSource.getXADataSource();
    XAConnection[] xaConn = new XAConnection[timeoutStatementsToExecute];
    XAResource xaRes = null;
    Connection conn = null;
    for (int i = 0; i < timeoutStatementsToExecute; i++) {
        xaConn[i] = xaDataSource.getXAConnection();
        xaRes = xaConn[i].getXAResource();
        conn = xaConn[i].getConnection();
        Xid xid = createXid(123, i);
        xaRes.setTransactionTimeout(8);
        xaRes.start(xid, XAResource.TMNOFLAGS);
        stm = conn.createStatement();
        stm.execute("insert into XATT values (" + i + ", 'Test_Entry')");
        if (i % timeoutCommitEveryStatement == 0) {
            stm.close();
            xaRes.end(xid, XAResource.TMSUCCESS);
            xaRes.prepare(xid);
            xaRes.commit(xid, false);
        } else if (i % 11 != 0) {
            // with failure.
            try {
                xaRes.end(xid, XAResource.TMFAIL);
                fail();
            } catch (XAException ex) {
                if (ex.errorCode < XAException.XA_RBBASE || ex.errorCode > XAException.XA_RBEND) {
                    throw ex;
                }
            }
            stm.close();
        } else if (i % 2 == 0) {
            // check the timeout for transactions disassociated
            // with success.
            xaRes.end(xid, XAResource.TMSUCCESS);
            stm.close();
        }
    }
    ResultSet rs = null;
    stm = getConnection().createStatement();
    rs = stm.executeQuery("select count(*) from XATT");
    rs.next();
    // Check whether the correct number of transactions
    // was rolled back
    assertTrue(rs.getInt(1) == timeoutStatementsCommitted);
    // test the timeout during the statement run
    XAConnection xaConn2 = xaDataSource.getXAConnection();
    xaRes = xaConn2.getXAResource();
    conn = xaConn2.getConnection();
    Xid xid = createXid(124, 100);
    xaRes.setTransactionTimeout(10);
    xaRes.start(xid, XAResource.TMNOFLAGS);
    stm = conn.createStatement();
    // and the appropriate exception was thrown
    try {
        // Run this kind of statement just to be sure
        // it will not finish before it will time out
        rs = stm.executeQuery("select count(*) from sys.syscolumns a, sys.syscolumns b, " + "sys.syscolumns c, sys.syscolumns d, sys.syscolumns e " + "group by a.referenceid, b.referenceid, c.referenceid, " + "d.referenceid");
        fail("An exception is expected here");
    } catch (SQLException ex) {
        // Check the sql state of the thrown exception
        assertSQLState(SQLState.LANG_STATEMENT_CANCELLED_OR_TIMED_OUT.substring(0, 5), ex);
    }
    // perform a select on the table just to be sure that all
    // the transactions were rolled back.
    stm = getConnection().createStatement();
    rs = stm.executeQuery("select count(*) from XATT");
    rs.next();
    // code).
    for (int i = 0; i < timeoutStatementsToExecute; i++) {
        assertNotNull(xaConn[i]);
        xaConn[i].close();
    }
    // Again, check whether the correct number of transactions
    // was rolled back
    assertTrue(rs.getInt(1) == timeoutStatementsCommitted);
}
Also used : XADataSource(javax.sql.XADataSource) XAResource(javax.transaction.xa.XAResource) Xid(javax.transaction.xa.Xid) XAException(javax.transaction.xa.XAException) SQLException(java.sql.SQLException) Statement(java.sql.Statement) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) ResultSet(java.sql.ResultSet) XAConnection(javax.sql.XAConnection)

Example 97 with XAConnection

use of javax.sql.XAConnection in project derby by apache.

the class XATransactionTest method testTransactionTimeoutAndJoin.

/**
 * DERBY-4232: Test that two branches can be joined after the timeout has
 * been set.
 */
public void testTransactionTimeoutAndJoin() throws Exception {
    XADataSource xads = J2EEDataSource.getXADataSource();
    XAConnection xac1 = xads.getXAConnection();
    XAResource xar1 = xac1.getXAResource();
    Xid xid1 = XATestUtil.getXid(4, 5, 6);
    // Start/end work in a new transaction
    xar1.setTransactionTimeout(500);
    xar1.start(xid1, XAResource.TMNOFLAGS);
    xar1.end(xid1, XAResource.TMSUCCESS);
    // Create a new branch that can be joined with the existing one
    XAConnection xac2 = xads.getXAConnection();
    XAResource xar2 = xac2.getXAResource();
    xar2.setTransactionTimeout(500);
    // Do some work on the new branch before joining (the bug won't be
    // reproduced if we join with a fresh branch)
    Xid xid2 = XATestUtil.getXid(4, 5, 7);
    xar2.start(xid2, XAResource.TMNOFLAGS);
    xar2.end(xid2, XAResource.TMSUCCESS);
    xar2.rollback(xid2);
    assertTrue("Branches can only be joined if RM is same", xar1.isSameRM(xar2));
    // Join the branches. This used to fail with XAER_PROTO on the
    // network client.
    xar2.start(xid1, XAResource.TMJOIN);
    // End the transaction and free up the resources
    xar2.end(xid1, XAResource.TMSUCCESS);
    xar2.rollback(xid1);
    xac1.close();
    xac2.close();
}
Also used : XADataSource(javax.sql.XADataSource) XAResource(javax.transaction.xa.XAResource) Xid(javax.transaction.xa.Xid) XAConnection(javax.sql.XAConnection)

Example 98 with XAConnection

use of javax.sql.XAConnection in project derby by apache.

the class XATransactionTest method testDerby5562ReadOnlyTimeout.

/**
 * <p>
 * Regression test case for DERBY-5562.
 * </p>
 *
 * <p>
 * The timer that aborts long-running transactions if a transaction timeout
 * has been specified, was not cancelled when preparing a read-only
 * transaction. Since read-only transactions are implicitly committed when
 * they are prepared, this meant that the timer would try to abort an
 * already completed transaction. In addition to printing a confusing
 * message in derby.log about the transaction being rolled back, when it
 * actually had been committed, this could also make the timer roll back
 * the wrong transaction, if a new transaction with the same Xid was
 * started later.
 * </p>
 *
 * <p>
 * This test case exposes the bug by running a read-only transaction with
 * a timeout and preparing it, and then starting a new transaction with the
 * same Xid and no timeout. The bug would cause the second transaction to
 * time out.
 * </p>
 */
public void testDerby5562ReadOnlyTimeout() throws InterruptedException, SQLException, XAException {
    XADataSource xads = J2EEDataSource.getXADataSource();
    XAConnection xac = xads.getXAConnection();
    XAResource xar = xac.getXAResource();
    Xid xid = createXid(55, 62);
    // Set a transaction timeout. This should be relatively short so that
    // the test case doesn't need to wait very long to trigger the timeout.
    // However, it needs to be long enough to let the first transaction go
    // through without hitting the timeout. Hopefully, four seconds is
    // enough. If the test case starts failing intermittently during the
    // first transaction, we might have to raise the timeout (and raise the
    // sleep time in the second transaction correspondingly).
    assertTrue(xar.setTransactionTimeout(4));
    // Start first transaction.
    xar.start(xid, XAResource.TMNOFLAGS);
    Connection c = xac.getConnection();
    Statement s = c.createStatement();
    JDBC.assertSingleValueResultSet(s.executeQuery("select * from sysibm.sysdummy1"), "Y");
    s.close();
    c.close();
    xar.end(xid, XAResource.TMSUCCESS);
    // Prepare the first transaction. Since it's a read-only transaction,
    // it'll be automatically committed, so there's no need to call commit.
    assertEquals("XA_RDONLY", XAResource.XA_RDONLY, xar.prepare(xid));
    // Reset the timeout for the second transaction.
    assertTrue(xar.setTransactionTimeout(0));
    // Start second transaction.
    xar.start(xid, XAResource.TMNOFLAGS);
    c = xac.getConnection();
    s = c.createStatement();
    JDBC.assertSingleValueResultSet(s.executeQuery("select * from sysibm.sysdummy1"), "Y");
    s.close();
    c.close();
    // Keep the transaction running so long that it must have exceeded the
    // timeout for the previous transaction.
    Thread.sleep(5000);
    // End the transaction. Since there's no timeout on this transaction,
    // it should work. Before DERBY-5562 was fixed, it would fail because
    // it had been rolled back by the timer from the previous transaction.
    xar.end(xid, XAResource.TMSUCCESS);
    assertEquals("XA_RDONLY", XAResource.XA_RDONLY, xar.prepare(xid));
    xac.close();
}
Also used : XADataSource(javax.sql.XADataSource) XAResource(javax.transaction.xa.XAResource) Xid(javax.transaction.xa.Xid) Statement(java.sql.Statement) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) XAConnection(javax.sql.XAConnection)

Example 99 with XAConnection

use of javax.sql.XAConnection in project h2database by h2database.

the class TestDataSource method testXAConnection.

private void testXAConnection(boolean userInDataSource) throws Exception {
    deleteDb("dataSource");
    JdbcDataSource ds = new JdbcDataSource();
    String url = getURL("dataSource", true);
    String user = getUser();
    ds.setURL(url);
    if (userInDataSource) {
        ds.setUser(user);
        ds.setPassword(getPassword());
    }
    if (userInDataSource) {
        assertEquals("ds" + ds.getTraceId() + ": url=" + url + " user=" + user, ds.toString());
    } else {
        assertEquals("ds" + ds.getTraceId() + ": url=" + url + " user=", ds.toString());
    }
    XAConnection xaConn;
    if (userInDataSource) {
        xaConn = ds.getXAConnection();
    } else {
        xaConn = ds.getXAConnection(user, getPassword());
    }
    int traceId = ((JdbcXAConnection) xaConn).getTraceId();
    assertTrue(xaConn.toString().startsWith("xads" + traceId + ": conn"));
    xaConn.addConnectionEventListener(new ConnectionEventListener() {

        @Override
        public void connectionClosed(ConnectionEvent event) {
        // nothing to do
        }

        @Override
        public void connectionErrorOccurred(ConnectionEvent event) {
        // nothing to do
        }
    });
    XAResource res = xaConn.getXAResource();
    assertFalse(res.setTransactionTimeout(1));
    assertEquals(0, res.getTransactionTimeout());
    assertTrue(res.isSameRM(res));
    assertFalse(res.isSameRM(null));
    Connection conn = xaConn.getConnection();
    assertEquals(user.toUpperCase(), conn.getMetaData().getUserName());
    Xid[] list = res.recover(XAResource.TMSTARTRSCAN);
    assertEquals(0, list.length);
    Statement stat = conn.createStatement();
    stat.execute("SELECT * FROM DUAL");
    conn.close();
    xaConn.close();
}
Also used : Statement(java.sql.Statement) JdbcDataSource(org.h2.jdbcx.JdbcDataSource) JdbcXAConnection(org.h2.jdbcx.JdbcXAConnection) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) JdbcXAConnection(org.h2.jdbcx.JdbcXAConnection) XAResource(javax.transaction.xa.XAResource) Xid(javax.transaction.xa.Xid) ConnectionEvent(javax.sql.ConnectionEvent) XAConnection(javax.sql.XAConnection) JdbcXAConnection(org.h2.jdbcx.JdbcXAConnection) ConnectionEventListener(javax.sql.ConnectionEventListener)

Example 100 with XAConnection

use of javax.sql.XAConnection in project h2database by h2database.

the class TestXA method testMixedXaNormal.

private void testMixedXaNormal() throws Exception {
    JdbcDataSource ds = new JdbcDataSource();
    ds.setURL("jdbc:h2:mem:test");
    ds.setUser("sa");
    ds.setPassword("");
    XAConnection xa = ds.getXAConnection();
    Connection c = xa.getConnection();
    assertTrue(c.getAutoCommit());
    MyXid xid = new MyXid();
    XAResource res = xa.getXAResource();
    res.start(xid, XAResource.TMNOFLAGS);
    assertFalse(c.getAutoCommit());
    res.end(xid, XAResource.TMSUCCESS);
    res.commit(xid, true);
    assertTrue(c.getAutoCommit());
    res.start(xid, XAResource.TMNOFLAGS);
    assertFalse(c.getAutoCommit());
    res.end(xid, XAResource.TMFAIL);
    res.rollback(xid);
    assertTrue(c.getAutoCommit());
    c.close();
    xa.close();
}
Also used : XAResource(javax.transaction.xa.XAResource) JdbcDataSource(org.h2.jdbcx.JdbcDataSource) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) XAConnection(javax.sql.XAConnection)

Aggregations

XAConnection (javax.sql.XAConnection)115 Connection (java.sql.Connection)78 XAResource (javax.transaction.xa.XAResource)56 XADataSource (javax.sql.XADataSource)52 Xid (javax.transaction.xa.Xid)44 Statement (java.sql.Statement)34 SQLException (java.sql.SQLException)30 PreparedStatement (java.sql.PreparedStatement)23 PooledConnection (javax.sql.PooledConnection)23 ResultSet (java.sql.ResultSet)22 CallableStatement (java.sql.CallableStatement)18 Test (org.junit.Test)18 XAException (javax.transaction.xa.XAException)16 Transaction (javax.transaction.Transaction)8 DataSource (javax.sql.DataSource)7 XidImpl (org.firebirdsql.jca.TestXABase.XidImpl)7 JdbcDataSource (org.h2.jdbcx.JdbcDataSource)7 NotSupportedException (javax.transaction.NotSupportedException)5 ConnectionPoolDataSource (javax.sql.ConnectionPoolDataSource)4 J2EEDataSource (org.apache.derbyTesting.junit.J2EEDataSource)4