private void postCommit() throws TransactionFailureException { TransactionFailureException cause = null; for (TransactionAware txAware : txAwares) { try { txAware.postTxCommit(); } catch (Throwable e) { String message = String.format("Unable to perform post-commit in transaction-aware '%s' for transaction %d. ", txAware.getTransactionAwareName(), currentTx.getTransactionId()); LOG.warn(message, e); cause = new TransactionFailureException(message, e); } } if (cause != null) { throw cause; } } }
@Test public void testPostCommitFailure() throws TransactionFailureException, InterruptedException { ds1.failPostCommitTxOnce = InduceFailure.ThrowException; // execute: add a change to ds1 and ds2 try { getExecutor().execute(testFunction, 10); Assert.fail("post commit failed - exception should be thrown"); } catch (TransactionFailureException e) { Assert.assertEquals("post failure", e.getCause().getMessage()); } // 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 testPersistAndRollbackFailure() throws TransactionFailureException, InterruptedException { ds1.failCommitTxOnce = InduceFailure.ThrowException; ds1.failRollbackTxOnce = InduceFailure.ThrowException; // execute: add a change to ds1 and ds2 try { getExecutor().execute(testFunction, 10); Assert.fail("persist failed - exception should be thrown"); } catch (TransactionFailureException e) { Assert.assertEquals("persist failure", e.getCause().getMessage()); } // verify both are rolled back and tx is invalidated Assert.assertTrue(ds1.started); Assert.assertTrue(ds2.started); Assert.assertTrue(ds1.checked); Assert.assertTrue(ds2.checked); Assert.assertTrue(ds1.committed); Assert.assertFalse(ds2.committed); Assert.assertFalse(ds1.postCommitted); Assert.assertFalse(ds2.postCommitted); Assert.assertTrue(ds1.rolledBack); Assert.assertTrue(ds2.rolledBack); Assert.assertEquals(txClient.state, DummyTxClient.CommitState.Invalidated); }
private void postCommit() throws TransactionFailureException { TransactionFailureException cause = null; for (TransactionAware txAware : txAwares) { try { txAware.postTxCommit(); } catch (Throwable e) { String message = String.format("Unable to perform post-commit in transaction-aware '%s' for transaction %d. ", txAware.getTransactionAwareName(), currentTx.getTransactionId()); LOG.warn(message, e); cause = new TransactionFailureException(message, e); } } if (cause != null) { throw cause; } } }
@Test public void testPersistFailure() throws TransactionFailureException, InterruptedException { ds1.failCommitTxOnce = InduceFailure.ThrowException; // execute: add a change to ds1 and ds2 try { getExecutor().execute(testFunction, 10); Assert.fail("persist failed - exception should be thrown"); } catch (TransactionFailureException e) { Assert.assertEquals("persist failure", e.getCause().getMessage()); } // verify both are rolled back and tx is aborted Assert.assertTrue(ds1.started); Assert.assertTrue(ds2.started); Assert.assertTrue(ds1.checked); Assert.assertTrue(ds2.checked); Assert.assertTrue(ds1.committed); Assert.assertFalse(ds2.committed); Assert.assertFalse(ds1.postCommitted); Assert.assertFalse(ds2.postCommitted); Assert.assertTrue(ds1.rolledBack); Assert.assertTrue(ds2.rolledBack); Assert.assertEquals(txClient.state, DummyTxClient.CommitState.Aborted); }
private void initFlowlet() throws InterruptedException { final TransactionContext txContext = flowletContext.createTransactionContext(); try { txContext.start(); try { LOG.info("Initializing flowlet: " + flowletContext); flowlet.initialize(flowletContext); LOG.info("Flowlet initialized: " + flowletContext); } catch (Throwable t) { LOG.error("User code exception. Aborting transaction.", t); txContext.abort(new TransactionFailureException("User code exception. Aborting transaction", t)); throw Throwables.propagate(t); } txContext.finish(); } catch (TransactionFailureException e) { LOG.error("Flowlet throws exception during flowlet initialize: " + flowletContext, e); throw Throwables.propagate(e); } }
@Test public void testFunctionAndRollbackFailure() throws TransactionFailureException, InterruptedException { ds1.failRollbackTxOnce = InduceFailure.ReturnFalse; // execute: add a change to ds1 and ds2 try { getExecutor().execute(testFunction, null); Assert.fail("function failed - exception should be thrown"); } catch (TransactionFailureException e) { Assert.assertEquals("function failed", e.getCause().getMessage()); } // verify both are rolled back and tx is invalidated Assert.assertTrue(ds1.started); Assert.assertTrue(ds2.started); Assert.assertFalse(ds1.checked); Assert.assertFalse(ds2.checked); Assert.assertFalse(ds1.committed); Assert.assertFalse(ds2.committed); Assert.assertFalse(ds1.postCommitted); Assert.assertFalse(ds2.postCommitted); Assert.assertTrue(ds1.rolledBack); Assert.assertTrue(ds2.rolledBack); Assert.assertEquals(txClient.state, DummyTxClient.CommitState.Invalidated); }
private void destroyFlowlet() { final TransactionContext txContext = flowletContext.createTransactionContext(); try { txContext.start(); try { LOG.info("Destroying flowlet: " + flowletContext); flowlet.destroy(); LOG.info("Flowlet destroyed: " + flowletContext); } catch (Throwable t) { LOG.error("User code exception. Aborting transaction.", t); txContext.abort(new TransactionFailureException("User code exception. Aborting transaction", t)); // No need to propagate, as it is shutting down. } txContext.finish(); } catch (TransactionFailureException e) { LOG.error("Flowlet throws exception during flowlet destroy: " + flowletContext, e); // No need to propagate, as it is shutting down. } }
@Test public void testStartAndRollbackFailure() throws TransactionFailureException, InterruptedException { ds1.failStartTxOnce = InduceFailure.ThrowException; // execute: add a change to ds1 and ds2 try { getExecutor().execute(testFunction, 10); Assert.fail("start failed - exception should be thrown"); } catch (TransactionFailureException e) { Assert.assertEquals("start failure", e.getCause().getMessage()); } // verify both are not rolled back and tx is aborted Assert.assertTrue(ds1.started); Assert.assertFalse(ds2.started); Assert.assertFalse(ds1.checked); Assert.assertFalse(ds2.checked); Assert.assertFalse(ds1.committed); Assert.assertFalse(ds2.committed); Assert.assertFalse(ds1.postCommitted); Assert.assertFalse(ds2.postCommitted); Assert.assertFalse(ds1.rolledBack); Assert.assertFalse(ds2.rolledBack); Assert.assertEquals(txClient.state, DummyTxClient.CommitState.Aborted); }
private void persist() throws TransactionFailureException { for (TransactionAware txAware : txAwares) { boolean success; Throwable cause = null; try { success = txAware.commitTx(); } catch (Throwable e) { success = false; cause = e; } if (!success) { String message = String.format("Unable to persist changes of transaction-aware '%s' for transaction %d. ", txAware.getTransactionAwareName(), currentTx.getTransactionId()); if (cause == null) { LOG.warn(message); } else { LOG.warn(message, cause); } abort(new TransactionFailureException(message, cause)); // abort will throw that exception } } }
@Test public void testChangesAndRollbackFailure() throws TransactionFailureException, InterruptedException { ds1.failChangesTxOnce = InduceFailure.ThrowException; ds1.failRollbackTxOnce = InduceFailure.ThrowException; // execute: add a change to ds1 and ds2 try { getExecutor().execute(testFunction, 10); Assert.fail("get changes failed - exception should be thrown"); } catch (TransactionFailureException e) { Assert.assertEquals("changes failure", e.getCause().getMessage()); } // verify both are rolled back and tx is invalidated Assert.assertTrue(ds1.started); Assert.assertTrue(ds2.started); Assert.assertTrue(ds1.checked); Assert.assertFalse(ds2.checked); Assert.assertFalse(ds1.committed); Assert.assertFalse(ds2.committed); Assert.assertFalse(ds1.postCommitted); Assert.assertFalse(ds2.postCommitted); Assert.assertTrue(ds1.rolledBack); Assert.assertTrue(ds2.rolledBack); Assert.assertEquals(txClient.state, DummyTxClient.CommitState.Invalidated); }
private void commit() throws TransactionFailureException { boolean commitSuccess = false; try { commitSuccess = txClient.commit(currentTx); } catch (TransactionNotInProgressException e) { String message = String.format("Transaction %d is not in progress.", currentTx.getTransactionId()); LOG.warn(message, e); abort(new TransactionFailureException(message, e)); // abort will throw that exception } catch (Throwable e) { String message = String.format("Exception from commit for transaction %d.", currentTx.getTransactionId()); LOG.warn(message, e); abort(new TransactionFailureException(message, e)); // abort will throw that exception } if (!commitSuccess) { String message = String.format("Conflict detected for transaction %d.", currentTx.getTransactionId()); abort(new TransactionConflictException(message)); // abort will throw } }
@Test public void testStartAndRollbackFailure() throws TransactionFailureException, InterruptedException { ds1.failStartTxOnce = InduceFailure.ThrowException; TransactionContext context = newTransactionContext(ds1, ds2); // start transaction try { context.start(); Assert.fail("start failed - exception should be thrown"); } catch (TransactionFailureException e) { Assert.assertEquals("start failure", e.getCause().getMessage()); } // verify both are not rolled back and tx is aborted Assert.assertTrue(ds1.started); Assert.assertFalse(ds2.started); Assert.assertFalse(ds1.checked); Assert.assertFalse(ds2.checked); Assert.assertFalse(ds1.committed); Assert.assertFalse(ds2.committed); Assert.assertFalse(ds1.postCommitted); Assert.assertFalse(ds2.postCommitted); Assert.assertFalse(ds1.rolledBack); Assert.assertFalse(ds2.rolledBack); Assert.assertEquals(txClient.state, DummyTxClient.CommitState.Aborted); }
private void persist() throws TransactionFailureException { for (TransactionAware txAware : txAwares) { boolean success; Throwable cause = null; try { success = txAware.commitTx(); } catch (Throwable e) { success = false; cause = e; } if (!success) { String message = String.format("Unable to persist changes of transaction-aware '%s' for transaction %d. ", txAware.getTransactionAwareName(), currentTx.getTransactionId()); if (cause == null) { LOG.warn(message); } else { LOG.warn(message, cause); } abort(new TransactionFailureException(message, cause)); // abort will throw that exception } } }
@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); }
private void commit() throws TransactionFailureException { boolean commitSuccess = false; try { commitSuccess = txClient.commit(currentTx); } catch (TransactionNotInProgressException e) { String message = String.format("Transaction %d is not in progress.", currentTx.getTransactionId()); LOG.warn(message, e); abort(new TransactionFailureException(message, e)); // abort will throw that exception } catch (Throwable e) { String message = String.format("Exception from commit for transaction %d.", currentTx.getTransactionId()); LOG.warn(message, e); abort(new TransactionFailureException(message, e)); // abort will throw that exception } if (!commitSuccess) { String message = String.format("Conflict detected for transaction %d.", currentTx.getTransactionId()); abort(new TransactionConflictException(message)); // abort will throw } }
@Test public void testPersistFailure() throws TransactionFailureException, InterruptedException { ds1.failCommitTxOnce = InduceFailure.ThrowException; TransactionContext context = newTransactionContext(ds1, ds2); // start transaction context.start(); // add a change to ds1 and ds2 ds1.addChange(A); ds2.addChange(B); // commit transaction should fail and cause rollback try { context.finish(); Assert.fail("Persist should have failed - exception should be thrown"); } catch (TransactionFailureException e) { Assert.assertEquals("persist failure", e.getCause().getMessage()); } // verify both are rolled back and tx is aborted Assert.assertTrue(ds1.started); Assert.assertTrue(ds2.started); Assert.assertTrue(ds1.checked); Assert.assertTrue(ds2.checked); Assert.assertTrue(ds1.committed); Assert.assertFalse(ds2.committed); Assert.assertFalse(ds1.postCommitted); Assert.assertFalse(ds2.postCommitted); Assert.assertTrue(ds1.rolledBack); Assert.assertTrue(ds2.rolledBack); Assert.assertEquals(txClient.state, DummyTxClient.CommitState.Aborted); }
txAware.getTransactionAwareName(), currentTx.getTransactionId()); LOG.warn(message, e); abort(new TransactionFailureException(message, e)); String message = String.format("Transaction %d is not in progress.", currentTx.getTransactionId()); LOG.warn(message, e); abort(new TransactionFailureException(message, e)); abort(new TransactionFailureException(message, e));
@Test public void testPersistAndRollbackFailure() throws TransactionFailureException, InterruptedException { ds1.failCommitTxOnce = InduceFailure.ThrowException; ds1.failRollbackTxOnce = InduceFailure.ThrowException; TransactionContext context = newTransactionContext(ds1, ds2); // start transaction context.start(); // add a change to ds1 and ds2 ds1.addChange(A); ds2.addChange(B); // commit transaction should fail and cause rollback try { context.finish(); Assert.fail("Persist should have failed - exception should be thrown"); } catch (TransactionFailureException e) { Assert.assertEquals("persist failure", e.getCause().getMessage()); } // verify both are rolled back and tx is invalidated Assert.assertTrue(ds1.started); Assert.assertTrue(ds2.started); Assert.assertTrue(ds1.checked); Assert.assertTrue(ds2.checked); Assert.assertTrue(ds1.committed); Assert.assertFalse(ds2.committed); Assert.assertFalse(ds1.postCommitted); Assert.assertFalse(ds2.postCommitted); Assert.assertTrue(ds1.rolledBack); Assert.assertTrue(ds2.rolledBack); Assert.assertEquals(txClient.state, DummyTxClient.CommitState.Invalidated); }
String message = String.format("Transaction %d is not in progress.", currentTx.getTransactionId()); LOG.warn(message, e); abort(new TransactionFailureException(message, e)); abort(new TransactionFailureException(message, e));