Search in sources :

Example 11 with TransactionFailureException

use of org.apache.tephra.TransactionFailureException in project cdap by caskdata.

the class AbstractTransactionContext method checkpoint.

@Override
public void checkpoint() throws TransactionFailureException {
    Preconditions.checkState(currentTx != null, "Cannot checkpoint tx that has not been started");
    persist();
    try {
        currentTx = txClient.checkpoint(currentTx);
        // update the current transaction with all TransactionAwares
        for (TransactionAware txAware : getTransactionAwares()) {
            txAware.updateTx(currentTx);
        }
    } catch (TransactionFailureException e) {
        abort(e);
    } catch (Throwable e) {
        abort(new TransactionFailureException(String.format("Exception from checkpoint for transaction %d.", currentTx.getTransactionId()), e));
    }
}
Also used : TransactionFailureException(org.apache.tephra.TransactionFailureException) TransactionAware(org.apache.tephra.TransactionAware)

Example 12 with TransactionFailureException

use of org.apache.tephra.TransactionFailureException in project cdap by caskdata.

the class QueueTest method testRollback.

@Test(timeout = TIMEOUT_MS)
public void testRollback() throws Exception {
    QueueName queueName = QueueName.fromFlowlet(NamespaceId.DEFAULT.getEntityName(), "app", "flow", "flowlet", "queuerollback");
    ConsumerConfig consumerConfig = new ConsumerConfig(0, 0, 1, DequeueStrategy.FIFO, null);
    configureGroups(queueName, ImmutableList.of(consumerConfig));
    try (QueueProducer producer = queueClientFactory.createProducer(queueName);
        QueueConsumer consumer = queueClientFactory.createConsumer(queueName, consumerConfig, 1)) {
        TransactionContext txContext = createTxContext(producer, consumer, new TransactionAware() {

            boolean canCommit = false;

            @Override
            public void startTx(Transaction tx) {
            }

            @Override
            public void updateTx(Transaction tx) {
            }

            @Override
            public Collection<byte[]> getTxChanges() {
                return ImmutableList.of();
            }

            @Override
            public boolean commitTx() throws Exception {
                // Flip-flop between commit success/failure.
                boolean res = canCommit;
                canCommit = !canCommit;
                return res;
            }

            @Override
            public void postTxCommit() {
            }

            @Override
            public boolean rollbackTx() throws Exception {
                return true;
            }

            @Override
            public String getTransactionAwareName() {
                return "test";
            }
        });
        // First, try to enqueue and commit would fail
        txContext.start();
        try {
            producer.enqueue(new QueueEntry(Bytes.toBytes(1)));
            txContext.finish();
            // If reaches here, it's wrong, as exception should be thrown.
            Assert.assertTrue(false);
        } catch (TransactionFailureException e) {
            txContext.abort();
        }
        // Try to enqueue again. Within the same transaction, dequeue should be empty.
        txContext.start();
        producer.enqueue(new QueueEntry(Bytes.toBytes(1)));
        Assert.assertTrue(consumer.dequeue().isEmpty());
        txContext.finish();
        // This time, enqueue has been committed, dequeue would see the item
        txContext.start();
        try {
            Assert.assertEquals(1, Bytes.toInt(consumer.dequeue().iterator().next()));
            txContext.finish();
            // If reaches here, it's wrong, as exception should be thrown.
            Assert.assertTrue(false);
        } catch (TransactionFailureException e) {
            txContext.abort();
        }
        // Dequeue again, since last tx was rollback, this dequeue should see the item again.
        txContext.start();
        Assert.assertEquals(1, Bytes.toInt(consumer.dequeue().iterator().next()));
        txContext.finish();
    }
}
Also used : QueueEntry(co.cask.cdap.data2.queue.QueueEntry) TransactionFailureException(org.apache.tephra.TransactionFailureException) TransactionFailureException(org.apache.tephra.TransactionFailureException) QueueConsumer(co.cask.cdap.data2.queue.QueueConsumer) Transaction(org.apache.tephra.Transaction) QueueProducer(co.cask.cdap.data2.queue.QueueProducer) TransactionContext(org.apache.tephra.TransactionContext) TransactionAware(org.apache.tephra.TransactionAware) Collection(java.util.Collection) ConsumerConfig(co.cask.cdap.data2.queue.ConsumerConfig) QueueName(co.cask.cdap.common.queue.QueueName) Test(org.junit.Test)

Example 13 with TransactionFailureException

use of org.apache.tephra.TransactionFailureException in project cdap by caskdata.

the class ObjectStoreDatasetTest method testInstantiateWrongClass.

@Test
public void testInstantiateWrongClass() throws Exception {
    DatasetId pairs = DatasetFrameworkTestUtil.NAMESPACE_ID.dataset("pairs");
    createObjectStoreInstance(pairs, new TypeToken<ImmutablePair<Integer, String>>() {
    }.getType());
    // note: due to type erasure, this succeeds
    final ObjectStoreDataset<Custom> store = dsFrameworkUtil.getInstance(pairs);
    TransactionExecutor storeTxnl = dsFrameworkUtil.newTransactionExecutor(store);
    // but now it must fail with incompatible type
    try {
        storeTxnl.execute(new TransactionExecutor.Subroutine() {

            @Override
            public void apply() throws Exception {
                Custom custom = new Custom(42, Lists.newArrayList("one", "two"));
                store.write(a, custom);
            }
        });
        Assert.fail("write should have failed with incompatible type");
    } catch (TransactionFailureException e) {
    // expected
    }
    // write a correct object to the pair store
    final ObjectStoreDataset<ImmutablePair<Integer, String>> pairStore = dsFrameworkUtil.getInstance(pairs);
    TransactionExecutor pairStoreTxnl = dsFrameworkUtil.newTransactionExecutor(pairStore);
    final ImmutablePair<Integer, String> pair = new ImmutablePair<>(1, "second");
    pairStoreTxnl.execute(new TransactionExecutor.Subroutine() {

        @Override
        public void apply() throws Exception {
            // should succeed
            pairStore.write(a, pair);
        }
    });
    pairStoreTxnl.execute(new TransactionExecutor.Subroutine() {

        @Override
        public void apply() throws Exception {
            ImmutablePair<Integer, String> actualPair = pairStore.read(a);
            Assert.assertEquals(pair, actualPair);
        }
    });
    // now try to read that as a custom object, should fail with class cast
    try {
        storeTxnl.execute(new TransactionExecutor.Subroutine() {

            @Override
            public void apply() throws Exception {
                Custom custom = store.read(a);
                Preconditions.checkNotNull(custom);
            }
        });
        Assert.fail("write should have failed with class cast exception");
    } catch (TransactionFailureException e) {
    // expected
    }
    pairStoreTxnl.execute(new TransactionExecutor.Subroutine() {

        @Override
        public void apply() throws Exception {
            deleteAndVerify(pairStore, a);
        }
    });
    dsFrameworkUtil.deleteInstance(pairs);
}
Also used : TransactionExecutor(org.apache.tephra.TransactionExecutor) TransactionFailureException(org.apache.tephra.TransactionFailureException) NoSuchElementException(java.util.NoSuchElementException) DatasetId(co.cask.cdap.proto.id.DatasetId) TransactionFailureException(org.apache.tephra.TransactionFailureException) ImmutablePair(co.cask.cdap.common.utils.ImmutablePair) TypeToken(com.google.common.reflect.TypeToken) Test(org.junit.Test)

Example 14 with TransactionFailureException

use of org.apache.tephra.TransactionFailureException in project cdap by caskdata.

the class TransactionContextTest method testPersistFailure.

@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);
}
Also used : TransactionFailureException(org.apache.tephra.TransactionFailureException) TransactionContext(org.apache.tephra.TransactionContext) Test(org.junit.Test)

Example 15 with TransactionFailureException

use of org.apache.tephra.TransactionFailureException in project cdap by caskdata.

the class TransactionContextTest method testPersistFalse.

@Test
public void testPersistFalse() throws TransactionFailureException, InterruptedException {
    ds1.failCommitTxOnce = InduceFailure.ReturnFalse;
    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) {
        // in this case, the ds simply returned false
        Assert.assertNull(e.getCause());
    }
    // 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);
}
Also used : TransactionFailureException(org.apache.tephra.TransactionFailureException) TransactionContext(org.apache.tephra.TransactionContext) Test(org.junit.Test)

Aggregations

TransactionFailureException (org.apache.tephra.TransactionFailureException)55 Test (org.junit.Test)19 TransactionContext (org.apache.tephra.TransactionContext)17 IOException (java.io.IOException)16 TransactionExecutor (org.apache.tephra.TransactionExecutor)12 TransactionConflictException (org.apache.tephra.TransactionConflictException)8 TxRunnable (co.cask.cdap.api.TxRunnable)6 DatasetContext (co.cask.cdap.api.data.DatasetContext)6 Location (org.apache.twill.filesystem.Location)6 TransactionAware (org.apache.tephra.TransactionAware)5 DataSetException (co.cask.cdap.api.dataset.DataSetException)4 DatasetManagementException (co.cask.cdap.api.dataset.DatasetManagementException)4 Table (co.cask.cdap.api.dataset.table.Table)4 ConsumerConfig (co.cask.cdap.data2.queue.ConsumerConfig)4 List (java.util.List)4 Map (java.util.Map)4 ArrayList (java.util.ArrayList)3 Collection (java.util.Collection)3 TimeoutException (java.util.concurrent.TimeoutException)3 Transaction (org.apache.tephra.Transaction)3