use of com.arjuna.ats.jta.recovery.XAResourceRecoveryHelper in project narayana by jbosstm.
the class RecoveryTest method test.
@Test
@BMRule(name = "throw lang error exception", targetClass = "org.h2.jdbcx.JdbcXAConnection", targetMethod = "commit", action = "throw new java.lang.Error()", targetLocation = "AT ENTRY")
public void test() throws Exception {
String url = "jdbc:arjuna:";
Properties p = System.getProperties();
p.put("jdbc.drivers", Driver.class.getName());
System.setProperties(p);
transactionalDriver = new TransactionalDriver();
DriverManager.registerDriver(transactionalDriver);
Properties dbProperties = new Properties();
final JdbcDataSource ds = new JdbcDataSource();
ds.setURL("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1");
dbProperties.put(TransactionalDriver.XADataSource, ds);
step0_setupTables(url, dbProperties);
// We need to do this in a different thread as otherwise the transaction would still be associated with the connection due to the java.lang.Error
// RMFAIL on it's own will cause H2 to close connection and that seems to discard the indoubt transactions
step1_leaveXidsInDbTable(url, dbProperties);
step2_checkDbIsNotCommitted(url, dbProperties);
// 3. Perform recovery
{
XARecoveryModule xarm = new XARecoveryModule();
xarm.addXAResourceRecoveryHelper(new XAResourceRecoveryHelper() {
@Override
public boolean initialise(String p) throws Exception {
return false;
}
@Override
public XAResource[] getXAResources() throws Exception {
return new XAResource[] { ds.getXAConnection().getXAResource() };
}
});
RecoveryManager manager = RecoveryManager.manager();
manager.removeAllModules(true);
manager.addModule(xarm);
AtomicActionRecoveryModule aarm = new AtomicActionRecoveryModule();
aarm.periodicWorkFirstPass();
Transformer.disableTriggers(true);
aarm.periodicWorkSecondPass();
Transformer.enableTriggers(true);
}
step4_finalDbCommitCheck(url, dbProperties);
}
use of com.arjuna.ats.jta.recovery.XAResourceRecoveryHelper in project narayana by jbosstm.
the class XARecoveryModule method resourceInitiatedRecoveryForRecoveryHelpers.
private List<XAResource> resourceInitiatedRecoveryForRecoveryHelpers() {
List<XAResource> xaresources = new ArrayList<XAResource>();
recoveryHelpersXAResource.clear();
for (XAResourceRecoveryHelper xaResourceRecoveryHelper : _xaResourceRecoveryHelpers) {
try {
XAResource[] xaResources = xaResourceRecoveryHelper.getXAResources();
if (xaResources != null) {
for (XAResource xaResource : xaResources) {
xaresources.add(xaResource);
}
recoveryHelpersXAResource.put(xaResourceRecoveryHelper, xaResources);
}
} catch (Exception ex) {
jtaLogger.i18NLogger.warn_recovery_getxaresource(ex);
}
}
return xaresources;
}
use of com.arjuna.ats.jta.recovery.XAResourceRecoveryHelper in project narayana by jbosstm.
the class XARecoveryModuleHelpersUnitTest method testTimelyXAResourceRecoveryHelperRemoval.
private void testTimelyXAResourceRecoveryHelperRemoval(final boolean somethingToRecover) throws Exception {
final XARecoveryModule xaRecoveryModule = new XARecoveryModule();
final long xAResourcesSleepMillis = 2000;
final long betweenPassesSleepMillis = 100;
final long millis = System.currentTimeMillis();
final SimpleResource testXAResource = new SimpleResource() {
@Override
public Xid[] recover(int i) throws XAException {
if (!somethingToRecover)
return new Xid[0];
return new Xid[] { new Xid() {
@Override
public int getFormatId() {
return 0;
}
@Override
public byte[] getGlobalTransactionId() {
return new byte[0];
}
@Override
public byte[] getBranchQualifier() {
return new byte[0];
}
} };
}
};
final XAResourceRecoveryHelper xaResourceRecoveryHelper = new XAResourceRecoveryHelper() {
@Override
public boolean initialise(String p) throws Exception {
return true;
}
@Override
public XAResource[] getXAResources() throws Exception {
System.out.printf("getXAResources sleep (%d)%n", System.currentTimeMillis() - millis);
Thread.sleep(xAResourcesSleepMillis);
System.out.printf("getXAResources return (%d)%n", System.currentTimeMillis() - millis);
return new XAResource[] { testXAResource };
}
};
final XAResourceRecoveryHelper xaResourceRecoveryHelper2 = new XAResourceRecoveryHelper() {
@Override
public boolean initialise(String p) throws Exception {
return true;
}
@Override
public XAResource[] getXAResources() throws Exception {
return new XAResource[0];
}
};
/*
* Remove helpers in the background whilst recovery is running to check that they are removed when
* the scanner is in the correct state.
* The sleep time param is tuned to ensure that the add/remove recovery helper operation occurs
* during pass 1.
*/
XAHelperRemover remover = new XAHelperRemover(xaResourceRecoveryHelper, xaRecoveryModule, xAResourcesSleepMillis / 2, false);
XAHelperRemover remover2 = new XAHelperRemover(xaResourceRecoveryHelper2, xaRecoveryModule, xAResourcesSleepMillis / 2, true);
xaRecoveryModule.addXAResourceRecoveryHelper(xaResourceRecoveryHelper);
remover.start();
remover2.start();
System.out.printf("Before pass 1 (%d)%n", System.currentTimeMillis() - millis);
xaRecoveryModule.periodicWorkFirstPass();
System.out.printf("Finished pass 1 (%d)%n", System.currentTimeMillis() - millis);
Thread.sleep(betweenPassesSleepMillis);
System.out.printf("Starting pass 2 (%d)%n", System.currentTimeMillis() - millis);
xaRecoveryModule.periodicWorkSecondPass();
System.out.printf("Finished pass 2 (%d)%n", System.currentTimeMillis() - millis);
// wait for helper removal threads to finish
try {
remover.join();
remover2.join();
} catch (InterruptedException e) {
fail("Test was interrupted whilst waiting for xa resource helper threads: " + e.getMessage());
}
if (somethingToRecover) {
assertEquals("helper removed in wrong state", 0, remover.getRemoveState());
} else {
// See https://issues.jboss.org/browse/JBTM-2717
assertEquals("helper removed in wrong state", 2, remover.getRemoveState());
}
// the unused helper should have been removed after pass 1
assertEquals("helper2 removed in wrong state", 2, remover2.getRemoveState());
}
use of com.arjuna.ats.jta.recovery.XAResourceRecoveryHelper in project narayana by jbosstm.
the class XARecoveryModuleHelpersUnitTest method testTimelyXAResourceRecoveryHelperRemoval3.
/**
* Test that recovery helpers can be added and removed during recovery pass 2
* (and not have to wait until pass 2 is complete)
* @throws Exception
*/
@BMScript("recovery-helper")
@Test
public void testTimelyXAResourceRecoveryHelperRemoval3() throws Exception {
final XARecoveryModule xaRecoveryModule = new XARecoveryModule();
ExecutorService pool = Executors.newFixedThreadPool(1);
new Thread() {
public void run() {
xaRecoveryModule.periodicWorkFirstPass();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
xaRecoveryModule.periodicWorkSecondPass();
}
}.start();
Future<String> future = pool.submit(new Callable<String>() {
@Override
public String call() throws Exception {
final XAResourceRecoveryHelper xaResourceRecoveryHelper = new XAResourceRecoveryHelper() {
@Override
public boolean initialise(String p) throws Exception {
return true;
}
@Override
public XAResource[] getXAResources() throws Exception {
return new XAResource[0];
}
};
return addHelper(xaRecoveryModule, xaResourceRecoveryHelper, 3);
}
});
String errMsg = future.get();
assertNull(errMsg, errMsg);
}
use of com.arjuna.ats.jta.recovery.XAResourceRecoveryHelper in project narayana by jbosstm.
the class TestCommitMarkableResourceFailAfterCommitTwoXAResources method doTest.
protected void doTest(final DataSource dataSource) throws Exception {
// Test code
Utils.createTables(dataSource.getConnection());
// We can't just instantiate one as we need to be using the
// same one as
// the transaction
// manager would have used to mark the transaction for GC
CommitMarkableResourceRecordRecoveryModule recoveryModule = null;
Vector recoveryModules = manager.getModules();
if (recoveryModules != null) {
Enumeration modules = recoveryModules.elements();
while (modules.hasMoreElements()) {
RecoveryModule m = (RecoveryModule) modules.nextElement();
if (m instanceof CommitMarkableResourceRecordRecoveryModule) {
recoveryModule = (CommitMarkableResourceRecordRecoveryModule) m;
} else if (m instanceof XARecoveryModule) {
XARecoveryModule xarm = (XARecoveryModule) m;
xarm.addXAResourceRecoveryHelper(new XAResourceRecoveryHelper() {
public boolean initialise(String p) throws Exception {
return true;
}
public XAResource[] getXAResources() throws Exception {
return new XAResource[] { xaResource };
}
});
}
}
}
// final Object o = new Object();
// synchronized (o) {
Thread foo = new Thread(new Runnable() {
public void run() {
try {
javax.transaction.TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
tm.begin();
Connection localJDBCConnection = dataSource.getConnection();
localJDBCConnection.setAutoCommit(false);
nonXAResource = new JDBCConnectableResource(localJDBCConnection);
tm.getTransaction().enlistResource(nonXAResource);
xaResource = new SimpleXAResource();
tm.getTransaction().enlistResource(xaResource);
xaResource2 = new SimpleXAResource2();
tm.getTransaction().enlistResource(xaResource2);
localJDBCConnection.createStatement().execute("INSERT INTO foo (bar) VALUES (1)");
tm.commit();
} catch (ExecuteException t) {
} catch (Exception e) {
e.printStackTrace();
failed = true;
} catch (Error e) {
}
}
});
foo.start();
foo.join();
assertFalse(failed);
Xid committed = ((JDBCConnectableResource) nonXAResource).getStartedXid();
assertNotNull(committed);
// The recovery module has to perform lookups
new InitialContext().rebind("commitmarkableresource", dataSource);
// Check if the item is still in the db
recoveryModule.periodicWorkFirstPass();
assertTrue(recoveryModule.wasCommitted("commitmarkableresource", committed));
recoveryModule.periodicWorkSecondPass();
// Now we need to correctly complete the transaction
manager.scan();
// Make sure the item is no longer in the DB, it will need two scans as
// second phase of the CommitMarkableResourceRecoveryModule will have
// executed before the AtomicActionRecoveryModule has been able to GC
// it
assertTrue(recoveryModule.wasCommitted("commitmarkableresource", committed));
recoveryModule.periodicWorkFirstPass();
recoveryModule.periodicWorkSecondPass();
assertFalse(recoveryModule.wasCommitted("commitmarkableresource", committed));
assertTrue(xaResource.wasCommitted());
assertFalse(xaResource.wasRolledback());
assertTrue(xaResource2.commitCalled());
assertFalse(xaResource2.rollbackCalled());
}
Aggregations