public Result[] get(List<Get> gets) throws IOException { try { transactionContext.start(); Result[] result = transactionAwareHTable.get(gets); transactionContext.finish(); return result; } catch (Exception e) { try { transactionContext.abort(); } catch (TransactionFailureException e1) { throw new IOException("Could not rollback transaction", e1); } } return null; }
public void execute(Runnable runnable) throws TransactionFailureException { TransactionContext txCtx = new TransactionContext(txSystemClient, (TransactionAware) dataset); txCtx.start(); try { runnable.run(); } catch (Throwable t) { txCtx.abort(new TransactionFailureException("runnable failed", t)); } txCtx.finish(); } }
void addTransactionAware(TransactionAware txAware) { if (this.txContext != null) { txContext.addTransactionAware(txAware); } else if (this.tx != null) { txAwares.add(txAware); assert (tx != null); txAware.startTx(tx); } }
@Override public void checkpoint(boolean hasUncommittedData) throws SQLException { if (hasUncommittedData) { try { if (txContext == null) { tx = txServiceClient.checkpoint(tx); } else { assert (txContext != null); txContext.checkpoint(); tx = txContext.getCurrentTransaction(); } } catch (TransactionFailureException e) { throw new SQLException(e); } } // Since we're querying our own table while mutating it, we must exclude // see our current mutations, otherwise we can get erroneous results // (for DELETE) // or get into an infinite loop (for UPSERT SELECT). if (txContext == null) { tx.setVisibility(VisibilityLevel.SNAPSHOT_EXCLUDE_CURRENT); } else { assert (txContext != null); txContext.getCurrentTransaction().setVisibility( VisibilityLevel.SNAPSHOT_EXCLUDE_CURRENT); } }
context.start(); Assert.fail("Start should have failed - exception should be thrown"); } catch (TransactionFailureException e) { Assert.assertEquals("start failure", e.getCause().getMessage()); Assert.assertNull(context.getCurrentTransaction()); context.start(); try { context.finish(); Assert.fail("Get changes should have failed - exception should be thrown"); } catch (TransactionFailureException e) { Assert.assertEquals("changes failure", e.getCause().getMessage()); Assert.assertNull(context.getCurrentTransaction()); context.start(); try { context.finish(); Assert.fail("Persist should have failed - exception should be thrown"); } catch (TransactionFailureException e) { Assert.assertEquals("persist failure", e.getCause().getMessage()); Assert.assertNull(context.getCurrentTransaction()); context.start(); try { context.abort(); Assert.fail("Rollback should have failed - exception should be thrown"); } catch (TransactionFailureException e) {
@Test public void testRollbackOfPartitionCreateThenDelete() throws Exception { PartitionedFileSet pfs = dsFrameworkUtil.getInstance(pfsInstance); TransactionContext txContext = new TransactionContext(txClient, (TransactionAware) pfs); txContext.start(); Assert.assertNull(pfs.getPartition(PARTITION_KEY)); Location outputLocation = createPartition(pfs, PARTITION_KEY, "file"); Assert.assertNotNull(pfs.getPartition(PARTITION_KEY)); pfs.dropPartition(PARTITION_KEY); txContext.abort(); // the file shouldn't exist because the transaction was aborted (AND because it was dropped at the end of the tx) Assert.assertFalse(outputLocation.exists()); }
TransactionContext txContext1 = new TransactionContext(txClient, (TransactionAware) dataset1); txContext1.start(); PartitionKey partitionKey1 = generateUniqueKey(); dataset1.getPartitionOutput(partitionKey1).addPartition(); txContext1.finish(); TransactionContext txContext2 = new TransactionContext(txClient, (TransactionAware) dataset2); txContext2.start(); SimplePartitionConsumer partitionConsumer = new SimplePartitionConsumer(dataset2); List<PartitionDetail> partitions = partitionConsumer.consumePartitions(); Assert.assertEquals(1, partitions.size()); Assert.assertEquals(partitionKey1, partitions.get(0).getPartitionKey()); txContext2.finish(); txContext1.start(); PartitionKey partitionKey2 = generateUniqueKey(); dataset1.getPartitionOutput(partitionKey2).addPartition(); TransactionContext txContext3 = new TransactionContext(txClient, (TransactionAware) dataset3); txContext3.start(); PartitionKey partitionKey3 = generateUniqueKey(); dataset3.getPartitionOutput(partitionKey3).addPartition(); txContext2.start(); txContext2.finish(); txContext2.start(); Assert.assertTrue(partitionConsumer.consumePartitions().isEmpty()); txContext2.finish();
private void finishExecute(TransactionContext txContext, TxRunnable runnable) throws TransactionFailureException { try { runnable.run(datasetCache); } catch (Exception e) { txContext.abort(new TransactionFailureException("Exception raised from TxRunnable.run() " + runnable, e)); } // The call the txContext.abort above will always have exception thrown // Hence we'll only reach here if and only if the runnable.run() returns normally. txContext.finish(); } }
@Test public void testAbortFailureThrowsFailureException() throws TransactionFailureException { TransactionContext context = new SimpleTransactionContext(new FailingTxClient(txManager)); context.start(); Assert.assertTrue(context.addTransactionAware(ds1)); ds1.addChange(A); try { context.finish(); Assert.fail("Finish should have failed - exception should be thrown"); } catch (TransactionFailureException e) { // expected } }
@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); }
@Override protected void startTransaction(TransactionContext txContext) throws TransactionFailureException { txContext.start(defaultTimeout); } };
public TephraTransactionContext(PhoenixConnection connection) throws SQLException { PhoenixTransactionClient client = connection.getQueryServices().initTransactionClient(getProvider()); assert (client instanceof TephraTransactionClient); this.txServiceClient = ((TephraTransactionClient)client).getTransactionClient(); this.txAwares = Collections.emptyList(); this.txContext = new TransactionContext(txServiceClient); }
@Override public <T> DataSetManager<T> getDataset(DatasetId datasetInstanceId) throws Exception { @SuppressWarnings("unchecked") final T dataSet = datasetFramework.getDataset(datasetInstanceId, new HashMap<String, String>(), null); try { final TransactionContext txContext; // not every dataset is TransactionAware. FileSets for example, are not transactional. if (dataSet instanceof TransactionAware) { TransactionAware txAwareDataset = (TransactionAware) dataSet; txContext = new TransactionContext(txSystemClient, Lists.newArrayList(txAwareDataset)); txContext.start(); } else { txContext = null; } return new UnitTestDatasetManager<>(dataSet, txContext); } catch (Exception e) { throw Throwables.propagate(e); } }
@Override public void abort() throws SQLException { if (txContext == null || !isTransactionRunning()) { return; } try { txContext.abort(); } catch (TransactionFailureException e) { throw new SQLExceptionInfo.Builder( SQLExceptionCode.TRANSACTION_FAILED) .setMessage(e.getMessage()).setRootCause(e).build() .buildException(); } }
@Override public void commit() throws SQLException { if (txContext == null || !isTransactionRunning()) { return; } try { txContext.finish(); } catch (TransactionFailureException e) { if (e instanceof TransactionConflictException) { throw new SQLExceptionInfo.Builder( SQLExceptionCode.TRANSACTION_CONFLICT_EXCEPTION) .setMessage(e.getMessage()).setRootCause(e).build() .buildException(); } throw new SQLExceptionInfo.Builder( SQLExceptionCode.TRANSACTION_FAILED) .setMessage(e.getMessage()).setRootCause(e).build() .buildException(); } }
private void persist() throws TransactionFailureException { for (TransactionAware txAware : txAwares) { boolean success = false; Throwable cause = null; try { success = txAware.commitTx(); } catch (Throwable e) { cause = e; } if (!success) { TransactionFailureException tfe = createTransactionFailure("persist changes of", txAware, cause); LOG.warn(tfe.getMessage()); // abort will throw that exception abort(tfe); } } }
private Transaction getCurrentTransaction() { return tx != null ? tx : txContext != null ? txContext.getCurrentTransaction() : null; }