@Override public long getTimestamp() { return delegate().getTimestamp(); }
protected long storeEmptyMetadata() { Preconditions.checkNotNull(txnMgr, "Transaction manager must not be null"); return txnMgr.runTaskThrowOnConflict(tx -> { putMetadataAndHashIndexTask(tx, tx.getTimestamp(), getEmptyMetadata()); return tx.getTimestamp(); }); }
@Override public void abort() { if (isTraceEnabled()) { trace(String.format("ABORT: timestamp=%d", delegate.getTimestamp())); } super.abort(); }
@Override public void commit() { if (isTraceEnabled()) { trace(String.format("COMMIT: timestamp=%d", delegate.getTimestamp())); } super.commit(); }
private long putWriteAndFailOnPreCommitConditionReturningStartTimestamp(WriteReference writeRef) { AtomicLong startTs = new AtomicLong(0); assertThatThrownBy(() -> serializableTxManager .runTaskWithConditionWithRetry( FailingPreCommitCondition::new, (txn, ignore) -> { put(txn, writeRef); startTs.set(txn.getTimestamp()); return null; })).isInstanceOf(RuntimeException.class); return startTs.get(); }
private long put(SerializableTransactionManager txm, TableReference table, String row, String val) { Cell cell = Cell.create(row.getBytes(StandardCharsets.UTF_8), COL.getBytes(StandardCharsets.UTF_8)); return txm.runTaskWithRetry(t -> { t.put(table, ImmutableMap.of(cell, val.getBytes(StandardCharsets.UTF_8))); return t.getTimestamp(); }); }
@Override public void put(TableReference tableRef, Map<Cell, byte[]> values) { if (isTraceEnabled()) { for (Map.Entry<Cell, byte[]> e : values.entrySet()) { Cell key = e.getKey(); byte[] value = e.getValue(); trace( "PUT: timestamp=%d table=%s row=%s column=%s value=%s", delegate.getTimestamp(), tableRef, toHex(key.getRowName()), toHex(key.getColumnName()), toHex(value)); } } super.put(tableRef, values); }
private Long writeInTransactionAndGetStartTimestamp(WriteReference writeRef) { return txManager.runTaskWithRetry(txn -> { put(txn, writeRef); return txn.getTimestamp(); }); }
public long addTodoWithIdAndReturnTimestamp(long id, Todo todo) { return transactionManager.runTaskWithRetry((transaction) -> { Cell thisCell = Cell.create(ValueType.FIXED_LONG.convertFromJava(id), TodoSchema.todoTextColumn()); Map<Cell, byte[]> write = ImmutableMap.of(thisCell, ValueType.STRING.convertFromJava(todo.text())); transaction.put(TodoSchema.todoTable(), write); return transaction.getTimestamp(); }); }
@Override protected void touchMetadataWhileMarkingUsedForConflicts(Transaction t, Iterable<Long> ids) { StreamTestStreamMetadataTable metaTable = tables.getStreamTestStreamMetadataTable(t); Set<StreamTestStreamMetadataTable.StreamTestStreamMetadataRow> rows = Sets.newHashSet(); for (Long id : ids) { rows.add(StreamTestStreamMetadataTable.StreamTestStreamMetadataRow.of(id)); } Map<StreamTestStreamMetadataTable.StreamTestStreamMetadataRow, StreamMetadata> metadatas = metaTable.getMetadatas(rows); for (Map.Entry<StreamTestStreamMetadataTable.StreamTestStreamMetadataRow, StreamMetadata> e : metadatas.entrySet()) { StreamMetadata metadata = e.getValue(); Preconditions.checkState(metadata.getStatus() == Status.STORED, "Stream: %s has status: %s", e.getKey().getId(), metadata.getStatus()); metaTable.putMetadata(e.getKey(), metadata); } SetView<StreamTestStreamMetadataTable.StreamTestStreamMetadataRow> missingRows = Sets.difference(rows, metadatas.keySet()); if (!missingRows.isEmpty()) { throw new IllegalStateException("Missing metadata rows for:" + missingRows + " rows: " + rows + " metadata: " + metadatas + " txn timestamp: " + t.getTimestamp()); } }
public long addNamespacedTodoWithIdAndReturnTimestamp(long id, String namespace, Todo todo) { return transactionManager.runTaskWithRetry(tx -> { TodoSchemaTableFactory.of().getNamespacedTodoTable(tx).put( NamespacedTodoTable.NamespacedTodoRow.of(namespace), NamespacedTodoTable.NamespacedTodoColumnValue.of( NamespacedTodoTable.NamespacedTodoColumn.of(id), todo.text())); return tx.getTimestamp(); }); }
@Override public void delete(TableReference tableRef, Set<Cell> keys) { if (isTraceEnabled()) { for (Cell key : keys) { trace( "DELETE: timestamp=%d table=%s row=%s column=%s", delegate.getTimestamp(), tableRef, toHex(key.getRowName()), toHex(key.getColumnName())); } } super.delete(tableRef, keys); }
@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 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 cleanupDropsCheckpointTable() { fromKvs.createTables(TEST_AND_CHECKPOINT_TABLES); fromTxManager.runTaskWithRetry(tx -> { tx.put(TEST_TABLE, ImmutableMap.of(TEST_CELL, TEST_VALUE1)); return tx.getTimestamp(); }); KeyValueServiceMigrator migrator = KeyValueServiceMigrators.setupMigrator(migratorSpec); migrator.setup(); migrator.migrate(); verify(toKvs, never()).dropTable(CHECKPOINT_TABLE); migrator.cleanup(); verify(toKvs, times(1)).dropTable(CHECKPOINT_TABLE); }
@Test public void deletedEntriesAreNotMigrated() { fromKvs.createTables(TEST_AND_CHECKPOINT_TABLES); fromTxManager.runTaskWithRetry(tx -> { tx.put(TEST_TABLE, ImmutableMap.of(TEST_CELL, TEST_VALUE1)); return tx.getTimestamp(); }); fromTxManager.runTaskWithRetry(tx -> { tx.delete(TEST_TABLE, ImmutableSet.of(TEST_CELL)); return tx.getTimestamp(); }); KeyValueServiceMigrator migrator = KeyValueServiceMigrators.setupMigrator(migratorSpec); migrator.setup(); migrator.migrate(); assertThat(toKvs.get(TEST_TABLE, ImmutableMap.of(TEST_CELL, Long.MAX_VALUE))).isEmpty(); }
@Test public void testLoadEmpty() { Assert.assertTrue(txManager.runTaskReadOnly( tx -> priorityStore.loadOldPriorities(tx, tx.getTimestamp())).isEmpty()); Assert.assertTrue(txManager.runTaskReadOnly( tx -> priorityStore.loadNewPriorities(tx)).isEmpty()); }
@Test public void testImmutableTs() throws Exception { final long firstTs = timestampService.getFreshTimestamp(); long startTs = txManager.runTaskThrowOnConflict(t -> { Assert.assertTrue(firstTs < txManager.getImmutableTimestamp()); Assert.assertTrue(txManager.getImmutableTimestamp() < t.getTimestamp()); Assert.assertTrue(t.getTimestamp() < timestampService.getFreshTimestamp()); return t.getTimestamp(); }); Assert.assertTrue(firstTs < txManager.getImmutableTimestamp()); Assert.assertTrue(startTs < txManager.getImmutableTimestamp()); }
@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."); }
@Test public void migrateRevertsUncommittedWritesAndMigratesMostRecentlyCommitted() { fromKvs.createTables(TEST_AND_CHECKPOINT_TABLES); fromTxManager.runTaskWithRetry(tx -> { tx.put(TEST_TABLE, ImmutableMap.of(TEST_CELL, TEST_VALUE1)); return tx.getTimestamp(); }); long uncommittedTs = fromServices.getTimestampService().getFreshTimestamp(); fromKvs.put(TEST_TABLE, ImmutableMap.of(TEST_CELL, TEST_VALUE2), uncommittedTs); KeyValueServiceMigrator migrator = KeyValueServiceMigrators.setupMigrator(migratorSpec); migrator.setup(); migrator.migrate(); assertThat(fromServices.getTransactionService().get(uncommittedTs)) .isEqualTo(TransactionConstants.FAILED_COMMIT_TS); assertThat(toKvs.get(TEST_TABLE, ImmutableMap.of(TEST_CELL, Long.MAX_VALUE)).get(TEST_CELL).getContents()) .containsExactly(TEST_VALUE1); }