@Test public void testOrderedOnePhase() throws Exception { System.setProperty("com.arjuna.ats.arjuna.common.propertiesFile", "jbossts-properties.xml"); Uid firstToCommit = new Uid(); Uid secondToCommit = new Uid(); AtomicAction A = new AtomicAction(); // These user defined records could wrap anything such as 1PC JDBC or messages OrderedOnePhaseAbstractRecord rec1 = new OrderedOnePhaseAbstractRecord(secondToCommit); OrderedOnePhaseAbstractRecord rec2 = new OrderedOnePhaseAbstractRecord(firstToCommit); A.begin(); // Doesn't matter of the order A.add(rec1); A.add(rec2); // Do some work you could save some concept of the work in the abstract record save_state // rec1.sendMessage // rec2.doSQL // This is just so we can see the opportunity for failure recovery rec1.causeTransientFailure(); // Commit, this would make sure the database (rec2) was committed first A.commit(); // This shows recovery working, we should see Uid2 called again, if you had encoded some // information in rec2 you could // maybe // retry the sending of a message or similar RecordTypeManager.manager() .add( new RecordTypeMap() { @Override public int getType() { return OrderedOnePhaseAbstractRecord.typeId(); } @Override public Class<? extends AbstractRecord> getRecordClass() { return OrderedOnePhaseAbstractRecord.class; } }); recoveryPropertyManager.getRecoveryEnvironmentBean().setRecoveryBackoffPeriod(1); RecoveryManager.manager(RecoveryManager.DIRECT_MANAGEMENT) .addModule(new AtomicActionRecoveryModule()); RecoveryManager.manager().scan(); }
/** * Run the recovery manager and observe recovery of the transaction. * * @throws Exception */ private static void recoverTransaction() throws Exception { ConfigParticipantRecordTypeMap map = new ConfigParticipantRecordTypeMap(); RecordTypeManager.manager().add(map); RecoveryManager recoveryManager = RecoverySetup.getAndConfigureRecoveryManager(); recoveryManager.scan(); System.out.println("'child-config' value = " + ConfigService.getCommittedValue("child-config")); System.out.println( "'parent-config' value = " + ConfigService.getCommittedValue("parent-config")); recoveryManager.terminate(); }
private XARecoveryModule getRecoveryModule() { for (RecoveryModule recoveryModule : ((Vector<RecoveryModule>) RecoveryManager.manager().getModules())) { if (recoveryModule instanceof XARecoveryModule) { return (XARecoveryModule) recoveryModule; } } return null; }
/** * This routine finds the new XAResource for the transaction that used the old resource we * couldn't serialize. It does this by looking up the XARecoveryModule in the recovery manager and * asking it for the XAResource. The recovery manager will then look through its list of * registered XARecoveryResource implementations for the appropriate instance. If the * XARecoveryModule hasn't been initialised yet then this routine will fail, but on the next scan * it should work. */ private final XAResource getNewXAResource() { RecoveryManager recMan = RecoveryManager.manager(); Vector recoveryModules = recMan.getModules(); if (recoveryModules != null) { Enumeration modules = recoveryModules.elements(); while (modules.hasMoreElements()) { RecoveryModule m = (RecoveryModule) modules.nextElement(); if (m instanceof XARecoveryModule) { /* * Blaargh! There are better ways to do this! */ return ((XARecoveryModule) m).getNewXAResource(this); } } } return null; }
private List<SerializableXAResourceDeserializer> getXAResourceDeserializers() { if (serializableXAResourceDeserializers != null) { return serializableXAResourceDeserializers; } synchronized (this) { if (serializableXAResourceDeserializers != null) { return serializableXAResourceDeserializers; } serializableXAResourceDeserializers = new ArrayList<SerializableXAResourceDeserializer>(); for (RecoveryModule recoveryModule : RecoveryManager.manager().getModules()) { if (recoveryModule instanceof XARecoveryModule) { XARecoveryModule xaRecoveryModule = (XARecoveryModule) recoveryModule; serializableXAResourceDeserializers.addAll( xaRecoveryModule.getSeriablizableXAResourceDeserializers()); return serializableXAResourceDeserializers; } } } return serializableXAResourceDeserializers; }
public static void main (String[] args) { boolean testMode = false; for (int i = 0; i < args.length; i++) { if (args[i].compareTo("-help") == 0) { System.out.println("Usage: com.arjuna.ats.arjuna.recovery.RecoveryManager [-help] [-test] [-version]"); System.exit(0); } if (args[i].compareTo("-version") == 0) { System.out.println("Version " + ConfigurationInfo.getVersion()); System.exit(0); } if (args[i].compareTo("-test") == 0) { testMode = true; } } try { RecoveryManager manager = null; try { manager = manager(); } catch(Throwable e) { if(testMode) { // in some test cases the recovery manager is killed and restarted in quick succession. // sometimes the O/S does not free up the port fast enough, so we can't reclaim it on restart. // For test mode only, we therefore have a simple backoff-retry kludge: System.err.println("Warning: got exception '"+e.toString()+"' on startup, will retry in 5 seconds in the hope it is transient."); try { Thread.sleep(5000); } catch(InterruptedException interruptedException) { // do nothing } manager = manager(); } else { throw e; } } if (testMode) { System.out.println("Ready"); } // this is never going to return because it only returns when shutdown is called and // there is nothing which is going to call shutdown. we probably aught to provide a // clean way of terminating this process. manager.waitForTermination(); } catch (Throwable e) { e.printStackTrace(); } }