@Override public void addTransactionAwares(Iterable<? extends TransactionAware> transactionAwares) { Iterables.addAll(this.transactionAwares, transactionAwares); if (transactionContext != null) { for (TransactionAware transactionAware : transactionAwares) { transactionContext.addTransactionAware(transactionAware); } } }
@Override public void addTransactionAware(TransactionAware transactionAware) { transactionAwares.add(transactionAware); if (transactionContext != null) { transactionContext.addTransactionAware(transactionAware); } }
/** * Create a new {@link TransactionContext} for this flowlet. Add all {@link TransactionAware}s to the context. * @return a new TransactionContext. */ public TransactionContext createTransactionContext() { transactionContext = dataFabricFacade.createTransactionManager(); for (TransactionAware transactionAware : transactionAwares) { this.transactionContext.addTransactionAware(transactionAware); } return transactionContext; }
@Test public void testAndThenRemoveOnFailure() throws TransactionFailureException { ds1.failCommitTxOnce = InduceFailure.ThrowException; TransactionContext context = newTransactionContext(); context.start(); Assert.assertTrue(context.addTransactionAware(ds1)); ds1.addChange(A); try { context.finish(); Assert.fail("Persist should have failed - exception should be thrown"); } catch (TransactionFailureException e) { Assert.assertEquals("persist failure", e.getCause().getMessage()); } Assert.assertTrue(context.removeTransactionAware(ds1)); // Verify ds1 is rolled back Assert.assertTrue(ds1.started); Assert.assertTrue(ds1.checked); Assert.assertTrue(ds1.committed); Assert.assertFalse(ds1.postCommitted); Assert.assertTrue(ds1.rolledBack); Assert.assertEquals(txClient.state, DummyTxClient.CommitState.Aborted); }
context.addTransactionAware(ds2);
@Test public void testAddThenSuccess() throws TransactionFailureException, InterruptedException { TransactionContext context = newTransactionContext(ds1); // start transaction context.start(); // add a change to ds1 ds1.addChange(A); // add ds2 to the tx context.addTransactionAware(ds2); // add a change to ds2 ds2.addChange(B); // commit transaction context.finish(); // verify both are committed and post-committed Assert.assertTrue(ds1.started); Assert.assertTrue(ds2.started); Assert.assertTrue(ds1.checked); Assert.assertTrue(ds2.checked); Assert.assertTrue(ds1.committed); Assert.assertTrue(ds2.committed); Assert.assertTrue(ds1.postCommitted); Assert.assertTrue(ds2.postCommitted); Assert.assertFalse(ds1.rolledBack); Assert.assertFalse(ds2.rolledBack); Assert.assertEquals(txClient.state, DummyTxClient.CommitState.Committed); }
@Test public void testAddThenRemoveSuccess() throws TransactionFailureException { TransactionContext context = newTransactionContext(); context.start(); Assert.assertTrue(context.addTransactionAware(ds1)); ds1.addChange(A); try { context.removeTransactionAware(ds1); Assert.fail("Removal of TransactionAware should fails when there is active transaction."); } catch (IllegalStateException e) { // Expected } context.finish(); Assert.assertTrue(context.removeTransactionAware(ds1)); // Removing a TransactionAware not added before should returns false Assert.assertFalse(context.removeTransactionAware(ds2)); // Verify ds1 is committed and post-committed Assert.assertTrue(ds1.started); Assert.assertTrue(ds1.checked); Assert.assertTrue(ds1.committed); Assert.assertTrue(ds1.postCommitted); Assert.assertFalse(ds1.rolledBack); // Verify nothing happen to ds2 Assert.assertFalse(ds2.started); Assert.assertFalse(ds2.checked); Assert.assertFalse(ds2.committed); Assert.assertFalse(ds2.postCommitted); Assert.assertFalse(ds2.rolledBack); Assert.assertEquals(txClient.state, DummyTxClient.CommitState.Committed); }