public void CommitRecoveryTest() { string log = "12345678-1234-1234-1234-123456789012\tCommitted\ttest4,\r12345678-1234-1234-1234-123456789013\tPrepared\ttest1,\r12345678-1234-1234-1234-123456789014\tNone\ttest2,\r12345678-1234-1234-1234-123456789012\tRollbacked\ttest3,"; using (StreamWriter sw = new StreamWriter(TwoPhaseCommit_Accessor.LogFileName)) { sw.Write(log); } TwoPhaseCommit_Accessor.isInitialized = false; Transaction context = new Transaction(); ResourceManagerList rms = new ResourceManagerList(MyRMTest.MockRM()); CommitedTransaction actual; actual = TwoPhaseCommit.Commit(context, rms); if (!actual.DoneEvent.WaitOne(2000)) { Assert.Fail("Timeout in commit"); } using (StreamReader sr = new StreamReader(TwoPhaseCommit_Accessor.LogFileName)) { log = sr.ReadToEnd(); } string expected = "12345678-1234-1234-1234-123456789012\tRollbacked\ttest4,\r12345678-1234-1234-1234-123456789013\tDone\ttest1,\r" + context.Id.ToString("d") + "\tDone\ttest,\r"; Assert.AreEqual(expected, log); }
public virtual void TestNullTPCs() { int numObjects = Random().Next(4) + 3; // between [3, 6] TwoPhaseCommit[] tpcs = new TwoPhaseCommit[numObjects]; bool setNull = false; for (int i = 0; i < tpcs.Length; i++) { bool isNull = Random().NextDouble() < 0.3; if (isNull) { setNull = true; tpcs[i] = null; } else { tpcs[i] = new TwoPhaseCommitImpl(false, false, false); } } if (!setNull) { // none of the TPCs were picked to be null, pick one at random int idx = Random().Next(numObjects); tpcs[idx] = null; } // following call would fail if TPCTool won't handle null TPCs properly TwoPhaseCommitTool.Execute(tpcs); }
/// <summary> /// Executes a 2-phase commit algorithm by first /// <seealso cref="TwoPhaseCommit#prepareCommit()"/> all objects and only if all succeed, /// it proceeds with <seealso cref="TwoPhaseCommit#commit()"/>. If any of the objects /// fail on either the preparation or actual commit, it terminates and /// <seealso cref="TwoPhaseCommit#rollback()"/> all of them. /// <p> /// <b>NOTE:</b> it may happen that an object fails to commit, after few have /// already successfully committed. this tool will still issue a rollback /// instruction on them as well, but depending on the implementation, it may /// not have any effect. /// <p> /// <b>NOTE:</b> if any of the objects are {@code null}, this method simply /// skips over them. /// </summary> /// <exception cref="PrepareCommitFailException"> /// if any of the objects fail to /// <seealso cref="TwoPhaseCommit#prepareCommit()"/> </exception> /// <exception cref="CommitFailException"> /// if any of the objects fail to <seealso cref="TwoPhaseCommit#commit()"/> </exception> public static void Execute(params TwoPhaseCommit[] objects) { TwoPhaseCommit tpc = null; try { // first, all should successfully prepareCommit() for (int i = 0; i < objects.Length; i++) { tpc = objects[i]; if (tpc != null) { tpc.PrepareCommit(); } } } catch (Exception t) { // first object that fails results in rollback all of them and // throwing an exception. Rollback(objects); throw new PrepareCommitFailException(t, tpc); } // If all successfully prepareCommit(), attempt the actual commit() try { for (int i = 0; i < objects.Length; i++) { tpc = objects[i]; if (tpc != null) { tpc.Commit(); } } } catch (Exception t) { // first object that fails results in rollback all of them and // throwing an exception. Rollback(objects); throw new CommitFailException(t, tpc); } }
public void CommitTestWithoutOldLog() { File.Delete(TwoPhaseCommit_Accessor.LogFileName); Transaction context = new Transaction(); ResourceManagerList rms = new ResourceManagerList(MyRMTest.MockRM()); CommitedTransaction actual; actual = TwoPhaseCommit.Commit(context, rms); if (!actual.DoneEvent.WaitOne(1000)) { Assert.Fail("Timeout in commit"); } string log; using (var sr = new StreamReader(TwoPhaseCommit_Accessor.LogFileName)) { log = sr.ReadToEnd(); } string expected = context.Id.ToString("d") + "\tDone\ttest,\r"; Assert.IsTrue(log.Contains(expected)); }
/// <summary> /// Sole constructor. </summary> public PrepareCommitFailException(Exception cause, TwoPhaseCommit obj) : base("prepareCommit() failed on " + obj, cause) { }
/// <summary> /// Sole constructor. </summary> public CommitFailException(Exception cause, TwoPhaseCommit obj) : base("commit() failed on " + obj, cause) { }