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);
}
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();
}
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();
}
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();
}
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();
}
Aggregations