use of io.cdap.cdap.api.dataset.DatasetAdmin in project cdap by cdapio.
the class TableTest method testBasicCompareAndSwapWithTx.
@Test
public void testBasicCompareAndSwapWithTx() throws Exception {
DatasetAdmin admin = getTableAdmin(CONTEXT1, MY_TABLE);
admin.create();
try (Table myTable1 = getTable(CONTEXT1, MY_TABLE);
Table myTable2 = getTable(CONTEXT1, MY_TABLE);
Table myTable3 = getTable(CONTEXT1, MY_TABLE);
Table myTable4 = getTable(CONTEXT1, MY_TABLE)) {
Transaction tx1 = txClient.startShort();
((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
((TransactionAware) myTable2).startTx(tx2);
Assert.assertTrue(myTable2.compareAndSwap(R1, C1, null, V3));
// start tx3 and TableAssert.verify same thing again
Transaction tx3 = txClient.startShort();
((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();
((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();
}
}
use of io.cdap.cdap.api.dataset.DatasetAdmin in project cdap by cdapio.
the class TableTest method testRollingBackPersistedChanges.
@Test
public void testRollingBackPersistedChanges() throws Exception {
DatasetAdmin admin = getTableAdmin(CONTEXT1, MY_TABLE);
admin.create();
try (Table myTable0 = getTable(CONTEXT1, MY_TABLE);
Table myTable1 = getTable(CONTEXT1, MY_TABLE);
Table myTable2 = getTable(CONTEXT1, MY_TABLE)) {
// write and commit one row/column
Transaction tx0 = txClient.startShort();
((TransactionAware) myTable0).startTx(tx0);
myTable0.put(R2, a(C2), a(V2));
txClient.canCommitOrThrow(tx0, ((TransactionAware) myTable0).getTxChanges());
Assert.assertTrue(((TransactionAware) myTable0).commitTx());
txClient.commitOrThrow(tx0);
((TransactionAware) myTable0).postTxCommit();
Transaction tx1 = txClient.startShort();
((TransactionAware) myTable1).startTx(tx1);
// write r1->c1,v1 but not commit
myTable1.put(R1, a(C1), a(V1));
// also overwrite the value from tx0
myTable1.put(R2, a(C2), a(V3));
// TableAssert.verify can see changes inside tx
TableAssert.assertRow(a(C1, V1), myTable1.get(R1, a(C1)));
// persisting changes
Assert.assertTrue(((TransactionAware) myTable1).commitTx());
// let's pretend that after persisting changes we still got conflict when finalizing tx, so
// rolling back changes
Assert.assertTrue(((TransactionAware) myTable1).rollbackTx());
// making tx visible
txClient.abort(tx1);
// start new tx
Transaction tx2 = txClient.startShort();
((TransactionAware) myTable2).startTx(tx2);
// TableAssert.verify don't see rolled back changes
TableAssert.assertRow(a(), myTable2.get(R1, a(C1)));
// TableAssert.verify we still see the previous value
TableAssert.assertRow(a(C2, V2), myTable2.get(R2, a(C2)));
} finally {
admin.drop();
}
}
use of io.cdap.cdap.api.dataset.DatasetAdmin in project cdap by cdapio.
the class TableTest method testMultiIncrementWithFlush.
private void testMultiIncrementWithFlush(boolean readless) throws Exception {
final String tableName = "incrFlush";
DatasetProperties props = TableProperties.builder().setReadlessIncrementSupport(readless).build();
DatasetAdmin admin = getTableAdmin(CONTEXT1, tableName, props);
admin.create();
Map<String, String> args = new HashMap<>();
if (readless) {
args.put(HBaseTable.SAFE_INCREMENTS, "true");
}
try (Table table = getTable(CONTEXT1, tableName, props, args);
Table table2 = getTable(CONTEXT1, tableName, props, args)) {
Transaction tx = txClient.startShort();
try {
((TransactionAware) table).startTx(tx);
// Write an increment, then flush it by calling commitTx.
table.increment(new Increment(R1, C1, 10L));
((TransactionAware) table).commitTx();
} finally {
// invalidate the tx, leaving an excluded write in the table
txClient.invalidate(tx.getTransactionId());
}
// validate the first write is not visible
tx = txClient.startShort();
try {
((TransactionAware) table).startTx(tx);
Assert.assertEquals(null, table.get(new Get(R1, C1)).getLong(C1));
} finally {
txClient.commitOrThrow(tx);
}
tx = txClient.startShort();
try {
((TransactionAware) table).startTx(tx);
// Write an increment, then flush it by calling commitTx.
table.increment(new Increment(R1, C1, 1L));
((TransactionAware) table).commitTx();
// Write another increment, from both table instances
table.increment(new Increment(R1, C1, 1L));
if (readless) {
((TransactionAware) table2).startTx(tx);
table2.increment(new Increment(R1, C1, 1L));
((TransactionAware) table2).commitTx();
}
((TransactionAware) table).commitTx();
} finally {
txClient.commitOrThrow(tx);
}
// validate all increments are visible to a new tx
tx = txClient.startShort();
try {
((TransactionAware) table).startTx(tx);
Assert.assertEquals(new Long(readless ? 3L : 2L), table.get(new Get(R1, C1)).getLong(C1));
} finally {
txClient.commitOrThrow(tx);
}
} finally {
// drop table
admin.drop();
}
}
use of io.cdap.cdap.api.dataset.DatasetAdmin in project cdap by cdapio.
the class TableTest method testBasicColumnRangeWithTx.
@Test
public void testBasicColumnRangeWithTx() throws Exception {
// todo: test more tx logic (or add to get/put unit-test)
DatasetAdmin admin = getTableAdmin(CONTEXT1, MY_TABLE);
admin.create();
try (Table myTable1 = getTable(CONTEXT1, MY_TABLE);
Table myTable2 = getTable(CONTEXT1, MY_TABLE)) {
// write test data and commit
Transaction tx1 = txClient.startShort();
((TransactionAware) myTable1).startTx(tx1);
myTable1.put(R1, a(C1, C2, C3, C4, C5), a(V1, V2, V3, V4, V5));
myTable1.put(R2, a(C1), a(V2));
txClient.canCommitOrThrow(tx1, ((TransactionAware) myTable1).getTxChanges());
Assert.assertTrue(((TransactionAware) myTable1).commitTx());
txClient.commitOrThrow(tx1);
// Now, we will test column range get
Transaction tx2 = txClient.startShort();
((TransactionAware) myTable2).startTx(tx2);
// bounded range
TableAssert.assertRow(a(C2, V2, C3, V3, C4, V4), myTable2.get(R1, C2, C5, Integer.MAX_VALUE));
// open start range
TableAssert.assertRow(a(C1, V1, C2, V2, C3, V3), myTable2.get(R1, null, C4, Integer.MAX_VALUE));
// open end range
TableAssert.assertRow(a(C3, V3, C4, V4, C5, V5), myTable2.get(R1, C3, null, Integer.MAX_VALUE));
// open ends range
TableAssert.assertRow(a(C1, V1, C2, V2, C3, V3, C4, V4, C5, V5), myTable2.get(R1, null, null, Integer.MAX_VALUE));
// same with limit
// bounded range with limit
TableAssert.assertRow(a(C2, V2), myTable2.get(R1, C2, C5, 1));
// open start range with limit
TableAssert.assertRow(a(C1, V1, C2, V2), myTable2.get(R1, null, C4, 2));
// open end range with limit
TableAssert.assertRow(a(C3, V3, C4, V4), myTable2.get(R1, C3, null, 2));
// open ends range with limit
TableAssert.assertRow(a(C1, V1, C2, V2, C3, V3, C4, V4), myTable2.get(R1, null, null, 4));
// adding/changing/removing some columns
myTable2.put(R1, a(C1, C2, C3), a(V4, V3, V2));
myTable2.delete(R1, a(C4));
txClient.canCommitOrThrow(tx2, ((TransactionAware) myTable2).getTxChanges());
Assert.assertTrue(((TransactionAware) myTable2).commitTx());
txClient.commitOrThrow(tx2);
// Checking that changes are reflected in new scans in new tx
Transaction tx3 = txClient.startShort();
// NOTE: table can be re-used betweet tx
((TransactionAware) myTable1).startTx(tx3);
TableAssert.assertRow(a(C2, V3, C3, V2), myTable1.get(R1, C2, C5, Integer.MAX_VALUE));
txClient.canCommitOrThrow(tx3, ((TransactionAware) myTable1).getTxChanges());
Assert.assertTrue(((TransactionAware) myTable1).commitTx());
txClient.commitOrThrow(tx3);
} finally {
admin.drop();
}
}
use of io.cdap.cdap.api.dataset.DatasetAdmin in project cdap by cdapio.
the class TableTest method testScanAndDelete.
@Test
public void testScanAndDelete() throws Exception {
DatasetAdmin admin = getTableAdmin(CONTEXT1, MY_TABLE);
admin.create();
try (Table myTable1 = getTable(CONTEXT1, MY_TABLE)) {
Transaction tx1 = txClient.startShort();
((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();
}
}
Aggregations