@Override public Transaction commitAndStartNewTransaction(Transaction tx) { tx.commit(); return createNewTransaction(); }
@Override public void commit(TransactionService txService) throws TransactionFailedException { delegate().commit(txService); }
@Override public void commit() throws TransactionFailedException { delegate().commit(); }
private void commitWriteWith(PreCommitCondition preCommitCondition, ConflictHandler conflictHandler) { Transaction transaction = startTransaction(preCommitCondition, conflictHandler); put(transaction, ROW, COLUMN, "100"); transaction.commit(); }
@Test public void testReadOnlySerializableTransactionsIgnoreReadWriteConflicts() { Transaction t0 = startTransaction(); put(t0, "row1", "col1", "100"); t0.commit(); Transaction t1 = startTransaction(); get(t1, "row1", "col1"); Transaction t2 = startTransaction(); put(t2, "row1", "col1", "101"); t2.commit(); // Succeeds, even though t1 is serializable, because it's read-only. t1.commit(); }
@Test public void testWriteWriteConflict2() { Transaction t2 = startTransaction(); Transaction t1 = startTransaction(); put(t1, "row1", "col1", "v1"); put(t2, "row1", "col1", "v2"); t1.commit(); try { t2.commit(); fail("Expected write-write conflict."); } catch (TransactionConflictException e) { // expected } }
@Test public void testWriteWriteConflict() { Transaction t1 = startTransaction(); Transaction t2 = startTransaction(); put(t1, "row1", "col1", "v1"); put(t2, "row1", "col1", "v2"); t1.commit(); try { t2.commit(); fail("Expected write-write conflict."); } catch (TransactionConflictException e) { // expected } }
@Test public void testNonPhantomRead() { String initialValue = "100"; Transaction t0 = startTransaction(); put(t0, "row1", "col1", initialValue); put(t0, "row2", "col1", initialValue); t0.commit(); Transaction t1 = startTransaction(); RowResult<byte[]> first = BatchingVisitables.getFirst(t1.getRange(TEST_TABLE, RangeRequest.builder().build())); put(t1, "row22", "col1", initialValue); Transaction t2 = startTransaction(); put(t2, "row11", "col1", initialValue); t2.commit(); t1.commit(); }
@Test public void testColumnRangeReadWriteEmptyRangeUnread() { byte[] row = PtBytes.toBytes("row1"); Transaction t1 = startTransaction(); Map<byte[], BatchingVisitable<Map.Entry<Cell, byte[]>>> columnRange = t1.getRowsColumnRange(TEST_TABLE, ImmutableList.of(row), BatchColumnRangeSelection.create(PtBytes.toBytes("col"), PtBytes.toBytes("col0"), 1)); // Intentionally not reading anything from the result, so we shouldn't get a conflict. // Write to avoid the read only path. put(t1, "row1_1", "col0", "v0"); Transaction t2 = startTransaction(); put(t2, "row1", "col", "v0"); t2.commit(); t1.commit(); }
private void writeCells(TableReference table, ImmutableMap<Cell, byte[]> cellsToWrite) { Transaction writeTransaction = txManager.createNewTransaction(); writeTransaction.put(table, cellsToWrite); writeTransaction.commit(); }
@Test public void testNoDirtyReads() { Transaction t1 = startTransaction(); Transaction t2 = startTransaction(); put(t2, "row1", "col1", "v1"); t2.commit(); assertNull(get(t1, "row1", "col1")); }
@Test public void testColumnSelection2() { String initialValue = "100"; Transaction t0 = startTransaction(); put(t0, "row1", "col1", initialValue); put(t0, "row1", "col2", initialValue); put(t0, "row2", "col1", initialValue); t0.commit(); Transaction t1 = startTransaction(); BatchingVisitables.copyToList(getRangeRetainingCol(t1, "col1")); BatchingVisitables.copyToList(getRangeRetainingCol(t1, "col2")); // We need to do at least one put so we don't get caught by the read only code path put(t1, "row22", "col2", initialValue); t1.commit(); }
@Test public void testNoNonRepeatableReads() { Transaction t0 = startTransaction(); put(t0, "row1", "col1", "v1"); t0.commit(); Transaction t1 = startTransaction(); assertEquals("v1", get(t1, "row1", "col1")); Transaction t2 = startTransaction(); put(t2, "row1", "col1", "v2"); t2.commit(); // Repeated read: should see original value. assertEquals("v1", get(t1, "row1", "col1")); Transaction t3 = startTransaction(); assertEquals("v2", get(t3, "row1", "col1")); }
@Test public void testWriteChangedConflictsNoThrow() { overrideConflictHandlerForTable(TABLE, ConflictHandler.RETRY_ON_VALUE_CHANGED); final Cell cell = Cell.create(PtBytes.toBytes("row1"), PtBytes.toBytes("column1")); Transaction t1 = txManager.createNewTransaction(); Transaction t2 = txManager.createNewTransaction(); t1.delete(TABLE, ImmutableSet.of(cell)); t2.delete(TABLE, ImmutableSet.of(cell)); t1.commit(); t2.commit(); }
private void writeColumns() { Transaction t1 = startTransaction(); int totalPuts = 101; byte[] row = PtBytes.toBytes("row1"); // Record expected results using byte ordering ImmutableSortedMap.Builder<Cell, byte[]> writes = ImmutableSortedMap .orderedBy(Ordering.from(UnsignedBytes.lexicographicalComparator()).onResultOf(Cell::getColumnName)); for (int i = 0; i < totalPuts; i++) { put(t1, "row1", "col" + i, "v" + i); writes.put(Cell.create(row, PtBytes.toBytes("col" + i)), PtBytes.toBytes("v" + i)); } t1.commit(); } }
@Test public void testRangesTransaction() { Transaction t = startTransaction(); put(t, "row1", "col1", "v1"); t.commit(); RangeRequest allRange = RangeRequest.builder().batchHint(3).build(); t = startTransaction(); verifyAllGetRangesImplsRangeSizes(t, allRange, 1); }
@Test public void writesNotAddedToSweepQueueOrKvsOnWriteWriteConflict() { Transaction t1 = txManager.createNewTransaction(); Transaction t2 = txManager.createNewTransaction(); put(t1, SINGLE_WRITE); put(t2, SINGLE_WRITE); t1.commit(); assertThatThrownBy(t2::commit).isInstanceOf(TransactionConflictException.class); verify(sweepQueue, times(1)).enqueue(anyList()); assertLatestEntryForCellInKvsAtTimestamp(TABLE_CONS, TEST_CELL, t1.getTimestamp()); }
@Test public void testWriteWriteConflictsDeletedThrow() { overrideConflictHandlerForTable(TABLE, ConflictHandler.RETRY_ON_WRITE_WRITE); final Cell cell = Cell.create(PtBytes.toBytes("row1"), PtBytes.toBytes("column1")); Transaction t1 = txManager.createNewTransaction(); Transaction t2 = txManager.createNewTransaction(); t1.delete(TABLE, ImmutableSet.of(cell)); t2.delete(TABLE, ImmutableSet.of(cell)); t1.commit(); try { t2.commit(); fail(); } catch (TransactionConflictException e) { // good } }
@Test public void writesAddedToSweepQueueOnNoConflict() { WriteReference firstWrite = WriteReference.write(TABLE_CONS, TEST_CELL); WriteReference secondWrite = WriteReference.write(TABLE_THOR, TEST_CELL); Transaction t1 = txManager.createNewTransaction(); Transaction t2 = txManager.createNewTransaction(); put(t1, firstWrite); put(t2, secondWrite); t1.commit(); assertThat(getEnqueuedWritesNumber(1)).containsExactly(WriteInfo.of(firstWrite, t1.getTimestamp())); assertLatestEntryForCellInKvsAtTimestamp(TABLE_CONS, TEST_CELL, t1.getTimestamp()); t2.commit(); assertThat(getEnqueuedWritesNumber(2)).containsExactly(WriteInfo.of(secondWrite, t2.getTimestamp())); assertLatestEntryForCellInKvsAtTimestamp(TABLE_THOR, TEST_CELL, t2.getTimestamp()); verify(sweepQueue, times(2)).enqueue(anyList()); }
@Test public void testThrowsIfSweepSentinelSeen() { Cell cell = Cell.create(PtBytes.toBytes("row1"), PtBytes.toBytes("column1")); Transaction t1 = txManager.createNewTransaction(); Transaction t2 = txManager.createNewTransaction(); t1.getTimestamp(); t2.getTimestamp(); t1.put(TABLE, ImmutableMap.of(cell, new byte[1])); t1.commit(); keyValueService.addGarbageCollectionSentinelValues(TABLE, ImmutableSet.of(cell)); assertThatExceptionOfType(TransactionFailedRetriableException.class) .isThrownBy(() -> t2.get(TABLE, ImmutableSet.of(cell))) .withMessageContaining("Tried to read a value that has been deleted."); }