Search in sources :

Example 76 with Transaction

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

the class TableTest method testBasicIncrementWriteWithTxSmall.

private void testBasicIncrementWriteWithTxSmall(boolean readless) throws Exception {
    DatasetProperties props = TableProperties.builder().setReadlessIncrementSupport(readless).build();
    DatasetAdmin admin = getTableAdmin(CONTEXT1, MY_TABLE, props);
    admin.create();
    Table myTable = getTable(CONTEXT1, MY_TABLE, props);
    // start 1st tx
    Transaction tx = txClient.startShort();
    ((TransactionAware) myTable).startTx(tx);
    myTable.increment(R1, a(C1), la(-3L));
    // we'll use this one to test that we can delete increment and increment again
    myTable.increment(R2, a(C2), la(5L));
    commitAndAssertSuccess(tx, (TransactionAware) myTable);
    // start 2nd tx
    tx = txClient.startShort();
    ((TransactionAware) myTable).startTx(tx);
    Assert.assertArrayEquals(Bytes.toBytes(-3L), myTable.get(R1, C1));
    myTable.increment(R1, a(C1), la(-3L));
    Assert.assertArrayEquals(Bytes.toBytes(-6L), myTable.get(R1, C1));
    Assert.assertArrayEquals(Bytes.toBytes(5L), myTable.get(R2, C2));
    myTable.delete(R2, C2);
    Assert.assertArrayEquals(null, myTable.get(R2, C2));
    commitAndAssertSuccess(tx, (TransactionAware) myTable);
    // start 3rd tx
    tx = txClient.startShort();
    ((TransactionAware) myTable).startTx(tx);
    Assert.assertArrayEquals(Bytes.toBytes(-6L), myTable.get(R1, C1));
    Assert.assertArrayEquals(null, myTable.get(R2, C2));
    myTable.increment(R2, a(C2), la(7L));
    Assert.assertArrayEquals(Bytes.toBytes(7L), myTable.get(R2, C2));
    commitAndAssertSuccess(tx, (TransactionAware) myTable);
    // start 4rd tx
    tx = txClient.startShort();
    ((TransactionAware) myTable).startTx(tx);
    Assert.assertArrayEquals(Bytes.toBytes(7L), myTable.get(R2, C2));
    commitAndAssertSuccess(tx, (TransactionAware) myTable);
    admin.drop();
}
Also used : Table(co.cask.cdap.api.dataset.table.Table) HBaseTable(co.cask.cdap.data2.dataset2.lib.table.hbase.HBaseTable) Transaction(org.apache.tephra.Transaction) TransactionAware(org.apache.tephra.TransactionAware) DatasetProperties(co.cask.cdap.api.dataset.DatasetProperties) DatasetAdmin(co.cask.cdap.api.dataset.DatasetAdmin)

Example 77 with Transaction

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

the class TableTest method testBasicCompareAndSwapWithTx.

@Test
public void testBasicCompareAndSwapWithTx() throws Exception {
    DatasetAdmin admin = getTableAdmin(CONTEXT1, MY_TABLE);
    admin.create();
    try {
        Transaction tx1 = txClient.startShort();
        Table myTable1 = getTable(CONTEXT1, MY_TABLE);
        ((TransactionAware) myTable1).startTx(tx1);
        // write r1->c1,v1 but not commit
        myTable1.put(R1, a(C1), a(V1));
        // write r1->c2,v2 but not commit
        Assert.assertTrue(myTable1.compareAndSwap(R1, C2, null, V5));
        // TableAssert.verify compare and swap result visible inside tx before commit
        TableAssert.assertRow(a(C1, V1, C2, V5), myTable1.get(R1, a(C1, C2)));
        Assert.assertArrayEquals(V1, myTable1.get(R1, C1));
        Assert.assertArrayEquals(V5, myTable1.get(R1, C2));
        Assert.assertArrayEquals(null, myTable1.get(R1, C3));
        TableAssert.assertRow(a(C1, V1, C2, V5), myTable1.get(R1));
        // these should fail
        Assert.assertFalse(myTable1.compareAndSwap(R1, C1, null, V1));
        Assert.assertFalse(myTable1.compareAndSwap(R1, C1, V2, V1));
        Assert.assertFalse(myTable1.compareAndSwap(R1, C2, null, V2));
        Assert.assertFalse(myTable1.compareAndSwap(R1, C2, V2, V1));
        // but this should succeed
        Assert.assertTrue(myTable1.compareAndSwap(R1, C2, V5, V2));
        // start new tx (doesn't see changes of the tx1)
        Transaction tx2 = txClient.startShort();
        // committing tx1 in stages to check races are handled well
        // * first, flush operations of table
        txClient.canCommitOrThrow(tx1, ((TransactionAware) myTable1).getTxChanges());
        Assert.assertTrue(((TransactionAware) myTable1).commitTx());
        // check that tx2 doesn't see changes (even though they were flushed) of tx1 by trying to compareAndSwap
        // assuming current value is null
        Table myTable2 = getTable(CONTEXT1, MY_TABLE);
        ((TransactionAware) myTable2).startTx(tx2);
        Assert.assertTrue(myTable2.compareAndSwap(R1, C1, null, V3));
        // start tx3 and TableAssert.verify same thing again
        Transaction tx3 = txClient.startShort();
        Table myTable3 = getTable(CONTEXT1, MY_TABLE);
        ((TransactionAware) myTable3).startTx(tx3);
        Assert.assertTrue(myTable3.compareAndSwap(R1, C1, null, V2));
        // * second, make tx visible
        txClient.commitOrThrow(tx1);
        // TableAssert.verify that tx2 cannot commit because of the conflicts...
        try {
            txClient.canCommitOrThrow(tx2, ((TransactionAware) myTable2).getTxChanges());
            Assert.fail("Conflict not detected!");
        } catch (TransactionConflictException e) {
        // expected
        }
        ((TransactionAware) myTable2).rollbackTx();
        txClient.abort(tx2);
        // start tx4 and TableAssert.verify that changes of tx1 are now visible
        Transaction tx4 = txClient.startShort();
        Table myTable4 = getTable(CONTEXT1, MY_TABLE);
        ((TransactionAware) myTable4).startTx(tx4);
        TableAssert.assertRow(a(C1, V1, C2, V2), myTable4.get(R1, a(C1, C2)));
        Assert.assertArrayEquals(V1, myTable4.get(R1, C1));
        Assert.assertArrayEquals(V2, myTable4.get(R1, C2));
        Assert.assertArrayEquals(null, myTable4.get(R1, C3));
        TableAssert.assertRow(a(C2, V2), myTable4.get(R1, a(C2)));
        TableAssert.assertRow(a(C1, V1, C2, V2), myTable4.get(R1));
        // tx3 still cannot see tx1 changes
        Assert.assertTrue(myTable3.compareAndSwap(R1, C2, null, V5));
        // and it cannot commit because its changes cause conflicts
        try {
            txClient.canCommitOrThrow(tx3, ((TransactionAware) myTable3).getTxChanges());
            Assert.fail("Conflict not detected!");
        } catch (TransactionConflictException e) {
        // expected
        }
        ((TransactionAware) myTable3).rollbackTx();
        txClient.abort(tx3);
        // TableAssert.verify we can do some ops with tx4 based on data written with tx1
        Assert.assertFalse(myTable4.compareAndSwap(R1, C1, null, V4));
        Assert.assertFalse(myTable4.compareAndSwap(R1, C2, null, V5));
        Assert.assertTrue(myTable4.compareAndSwap(R1, C1, V1, V3));
        Assert.assertTrue(myTable4.compareAndSwap(R1, C2, V2, V4));
        myTable4.delete(R1, a(C1));
        // committing tx4
        txClient.canCommitOrThrow(tx4, ((TransactionAware) myTable3).getTxChanges());
        Assert.assertTrue(((TransactionAware) myTable4).commitTx());
        txClient.commitOrThrow(tx4);
        // TableAssert.verifying the result contents in next transaction
        Transaction tx5 = txClient.startShort();
        // NOTE: table instance can be re-used in series of transactions
        ((TransactionAware) myTable4).startTx(tx5);
        TableAssert.assertRow(a(C2, V4), myTable4.get(R1, a(C1, C2)));
        Assert.assertArrayEquals(null, myTable4.get(R1, C1));
        Assert.assertArrayEquals(V4, myTable4.get(R1, C2));
        TableAssert.assertRow(a(C2, V4), myTable4.get(R1));
        txClient.canCommitOrThrow(tx5, ((TransactionAware) myTable3).getTxChanges());
        Assert.assertTrue(((TransactionAware) myTable3).commitTx());
        txClient.commitOrThrow(tx5);
    } finally {
        admin.drop();
    }
}
Also used : Table(co.cask.cdap.api.dataset.table.Table) HBaseTable(co.cask.cdap.data2.dataset2.lib.table.hbase.HBaseTable) Transaction(org.apache.tephra.Transaction) TransactionAware(org.apache.tephra.TransactionAware) DatasetAdmin(co.cask.cdap.api.dataset.DatasetAdmin) TransactionConflictException(org.apache.tephra.TransactionConflictException) Test(org.junit.Test)

Example 78 with Transaction

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

the class TableTest method testClientSurvivesTableReset.

// this test ensures that an existing client survives the truncating or dropping and recreating of a table
@Test
public void testClientSurvivesTableReset() throws Exception {
    final String tableName = "survive";
    DatasetAdmin admin = getTableAdmin(CONTEXT1, tableName);
    admin.create();
    Table table = getTable(CONTEXT1, tableName);
    // write some values
    Transaction tx0 = txClient.startShort();
    ((TransactionAware) table).startTx(tx0);
    table.put(R1, a(C1), a(V1));
    txClient.canCommitOrThrow(tx0, ((TransactionAware) table).getTxChanges());
    Assert.assertTrue(((TransactionAware) table).commitTx());
    txClient.commitOrThrow(tx0);
    ((TransactionAware) table).postTxCommit();
    // TableAssert.verify
    Transaction tx1 = txClient.startShort();
    ((TransactionAware) table).startTx(tx1);
    TableAssert.assertRow(a(C1, V1), table.get(R1));
    // drop table and recreate
    admin.drop();
    admin.create();
    // TableAssert.verify can read but nothing there
    TableAssert.assertRow(a(), table.get(R1));
    // only did read, safe to abort
    txClient.abort(tx1);
    // create a new client and write another value
    Table table2 = getTable(CONTEXT1, tableName);
    Transaction tx2 = txClient.startShort();
    ((TransactionAware) table2).startTx(tx2);
    table2.put(R1, a(C2), a(V2));
    txClient.canCommitOrThrow(tx2, ((TransactionAware) table2).getTxChanges());
    Assert.assertTrue(((TransactionAware) table2).commitTx());
    txClient.commitOrThrow(tx2);
    ((TransactionAware) table2).postTxCommit();
    // TableAssert.verify it is visible
    Transaction tx3 = txClient.startShort();
    ((TransactionAware) table).startTx(tx3);
    TableAssert.assertRow(a(C2, V2), table.get(R1));
    // truncate table
    admin.truncate();
    // TableAssert.verify can read but nothing there
    TableAssert.assertRow(a(), table.get(R1));
    // only did read, safe to abort
    txClient.abort(tx3);
    // write again with other client
    Transaction tx4 = txClient.startShort();
    ((TransactionAware) table2).startTx(tx4);
    table2.put(R1, a(C3), a(V3));
    txClient.canCommitOrThrow(tx4, ((TransactionAware) table2).getTxChanges());
    Assert.assertTrue(((TransactionAware) table2).commitTx());
    txClient.commitOrThrow(tx4);
    ((TransactionAware) table2).postTxCommit();
    // TableAssert.verify it is visible
    Transaction tx5 = txClient.startShort();
    ((TransactionAware) table).startTx(tx5);
    TableAssert.assertRow(a(C3, V3), table.get(R1));
    // only did read, safe to abort
    txClient.abort(tx5);
    // drop table
    admin.drop();
}
Also used : Table(co.cask.cdap.api.dataset.table.Table) HBaseTable(co.cask.cdap.data2.dataset2.lib.table.hbase.HBaseTable) Transaction(org.apache.tephra.Transaction) TransactionAware(org.apache.tephra.TransactionAware) DatasetAdmin(co.cask.cdap.api.dataset.DatasetAdmin) Test(org.junit.Test)

Example 79 with Transaction

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

the class TableTest method testMultiGetWithEmpty.

@Test
public void testMultiGetWithEmpty() throws Exception {
    DatasetAdmin admin = getTableAdmin(CONTEXT1, MY_TABLE);
    admin.create();
    try {
        Transaction tx = txClient.startShort();
        Table myTable = getTable(CONTEXT1, MY_TABLE);
        ((TransactionAware) myTable).startTx(tx);
        myTable.put(R1, C1, V1);
        myTable.put(R1, C2, V2);
        myTable.put(R1, C3, V3);
        myTable.put(R1, C4, V4);
        List<Get> gets = new ArrayList<>();
        // the second and fourth Gets are requesting 0 columns. This tests correctness of batch-get logic, when there
        // is/are empty Gets among them.
        gets.add(new Get(R1, C1));
        gets.add(new Get(R1, ImmutableList.<byte[]>of()));
        gets.add(new Get(R1, C2, C3));
        gets.add(new Get(R1, ImmutableList.<byte[]>of()));
        gets.add(new Get(R1, C4));
        List<Row> rows = myTable.get(gets);
        // first off, the Gets at index two and four should be empty
        Assert.assertEquals(0, rows.get(1).getColumns().size());
        Assert.assertEquals(0, rows.get(3).getColumns().size());
        // verify the results of the other Gets
        Assert.assertEquals(1, rows.get(0).getColumns().size());
        Assert.assertArrayEquals(V1, rows.get(0).get(C1));
        Assert.assertEquals(2, rows.get(2).getColumns().size());
        Assert.assertArrayEquals(V2, rows.get(2).get(C2));
        Assert.assertArrayEquals(V3, rows.get(2).get(C3));
        Assert.assertEquals(1, rows.get(4).getColumns().size());
        Assert.assertArrayEquals(V4, rows.get(4).get(C4));
        txClient.abort(tx);
    } finally {
        admin.drop();
    }
}
Also used : Table(co.cask.cdap.api.dataset.table.Table) HBaseTable(co.cask.cdap.data2.dataset2.lib.table.hbase.HBaseTable) Transaction(org.apache.tephra.Transaction) TransactionAware(org.apache.tephra.TransactionAware) Get(co.cask.cdap.api.dataset.table.Get) ArrayList(java.util.ArrayList) DatasetAdmin(co.cask.cdap.api.dataset.DatasetAdmin) Row(co.cask.cdap.api.dataset.table.Row) Test(org.junit.Test)

Example 80 with Transaction

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

the class TableTest method testScanAndDelete.

@Test
public void testScanAndDelete() throws Exception {
    DatasetAdmin admin = getTableAdmin(CONTEXT1, MY_TABLE);
    admin.create();
    try {
        // 
        Transaction tx1 = txClient.startShort();
        Table myTable1 = getTable(CONTEXT1, MY_TABLE);
        ((TransactionAware) myTable1).startTx(tx1);
        myTable1.put(Bytes.toBytes("1_09a"), a(C1), a(V1));
        txClient.canCommitOrThrow(tx1, ((TransactionAware) myTable1).getTxChanges());
        Assert.assertTrue(((TransactionAware) myTable1).commitTx());
        txClient.commitOrThrow(tx1);
        // 
        Transaction tx2 = txClient.startShort();
        ((TransactionAware) myTable1).startTx(tx2);
        myTable1.delete(Bytes.toBytes("1_09a"));
        myTable1.put(Bytes.toBytes("1_08a"), a(C1), a(V1));
        myTable1.put(Bytes.toBytes("1_09b"), a(C1), a(V1));
        txClient.canCommitOrThrow(tx2, ((TransactionAware) myTable1).getTxChanges());
        Assert.assertTrue(((TransactionAware) myTable1).commitTx());
        txClient.commitOrThrow(tx2);
        // 
        Transaction tx3 = txClient.startShort();
        ((TransactionAware) myTable1).startTx(tx3);
        TableAssert.assertScan(a(Bytes.toBytes("1_08a"), Bytes.toBytes("1_09b")), aa(a(C1, V1), a(C1, V1)), myTable1, new Scan(Bytes.toBytes("1_"), Bytes.toBytes("2_")));
        myTable1.delete(Bytes.toBytes("1_08a"));
        myTable1.put(Bytes.toBytes("1_07a"), a(C1), a(V1));
        myTable1.delete(Bytes.toBytes("1_09b"));
        myTable1.put(Bytes.toBytes("1_08b"), a(C1), a(V1));
        myTable1.put(Bytes.toBytes("1_09c"), a(C1), a(V1));
        txClient.canCommitOrThrow(tx3, ((TransactionAware) myTable1).getTxChanges());
        Assert.assertTrue(((TransactionAware) myTable1).commitTx());
        txClient.commitOrThrow(tx3);
        // Now, we will test scans
        Transaction tx4 = txClient.startShort();
        ((TransactionAware) myTable1).startTx(tx4);
        TableAssert.assertScan(a(Bytes.toBytes("1_07a"), Bytes.toBytes("1_08b"), Bytes.toBytes("1_09c")), aa(a(C1, V1), a(C1, V1), a(C1, V1)), myTable1, new Scan(Bytes.toBytes("1_"), Bytes.toBytes("2_")));
    } finally {
        admin.drop();
    }
}
Also used : Table(co.cask.cdap.api.dataset.table.Table) HBaseTable(co.cask.cdap.data2.dataset2.lib.table.hbase.HBaseTable) Transaction(org.apache.tephra.Transaction) TransactionAware(org.apache.tephra.TransactionAware) DatasetAdmin(co.cask.cdap.api.dataset.DatasetAdmin) Scan(co.cask.cdap.api.dataset.table.Scan) Test(org.junit.Test)

Aggregations

Transaction (org.apache.tephra.Transaction)99 Test (org.junit.Test)54 TransactionAware (org.apache.tephra.TransactionAware)34 Table (co.cask.cdap.api.dataset.table.Table)29 DatasetAdmin (co.cask.cdap.api.dataset.DatasetAdmin)27 HBaseTable (co.cask.cdap.data2.dataset2.lib.table.hbase.HBaseTable)22 Put (co.cask.cdap.api.dataset.table.Put)12 DatasetProperties (co.cask.cdap.api.dataset.DatasetProperties)11 Get (co.cask.cdap.api.dataset.table.Get)10 TransactionSystemClient (org.apache.tephra.TransactionSystemClient)10 Row (co.cask.cdap.api.dataset.table.Row)8 ConsumerConfig (co.cask.cdap.data2.queue.ConsumerConfig)8 KeyStructValueTableDefinition (co.cask.cdap.explore.service.datasets.KeyStructValueTableDefinition)8 Scan (co.cask.cdap.api.dataset.table.Scan)7 ArrayList (java.util.ArrayList)7 CConfiguration (co.cask.cdap.common.conf.CConfiguration)6 ExploreExecutionResult (co.cask.cdap.explore.client.ExploreExecutionResult)6 DatasetId (co.cask.cdap.proto.id.DatasetId)6 IOException (java.io.IOException)6 BufferingTableTest (co.cask.cdap.data2.dataset2.lib.table.BufferingTableTest)5