use of com.scalar.db.api.Put in project scalardb by scalar-labs.
the class ConsensusCommitIntegrationTestBase method putAndCommit_SinglePartitionMutationsGiven_ShouldAccessStorageOnceForPrepareAndCommit.
@Test
public void putAndCommit_SinglePartitionMutationsGiven_ShouldAccessStorageOnceForPrepareAndCommit() throws CommitException, UnknownTransactionStatusException, ExecutionException, CoordinatorException {
// Arrange
IntValue balance = new IntValue(BALANCE, INITIAL_BALANCE);
List<Put> puts = preparePuts(namespace1, TABLE_1);
puts.get(0).withValue(balance);
puts.get(1).withValue(balance);
ConsensusCommit transaction = manager.start();
// Act
transaction.put(puts.get(0));
transaction.put(puts.get(1));
transaction.commit();
// Assert
// one for prepare, one for commit
verify(storage, times(2)).mutate(anyList());
verify(coordinator).putState(any(Coordinator.State.class));
}
use of com.scalar.db.api.Put in project scalardb by scalar-labs.
the class ConsensusCommitIntegrationTestBase method commit_WriteSkewOnExistingRecordsWithSerializableWithExtraRead_OneShouldCommitTheOtherShouldThrowCommitConflictException.
private void commit_WriteSkewOnExistingRecordsWithSerializableWithExtraRead_OneShouldCommitTheOtherShouldThrowCommitConflictException(String namespace1, String table1, String namespace2, String table2) throws CommitException, UnknownTransactionStatusException, CrudException {
// Arrange
List<Put> puts = Arrays.asList(preparePut(0, 0, namespace1, table1).withValue(BALANCE, 1), preparePut(0, 1, namespace2, table2).withValue(BALANCE, 1));
ConsensusCommit transaction = manager.start(Isolation.SERIALIZABLE, SerializableStrategy.EXTRA_READ);
transaction.put(puts);
transaction.commit();
// Act
ConsensusCommit transaction1 = manager.start(Isolation.SERIALIZABLE, SerializableStrategy.EXTRA_READ);
ConsensusCommit transaction2 = manager.start(Isolation.SERIALIZABLE, SerializableStrategy.EXTRA_READ);
Get get1_1 = prepareGet(0, 1, namespace2, table2);
Optional<Result> result1 = transaction1.get(get1_1);
assertThat(result1).isPresent();
int current1 = getBalance(result1.get());
Get get1_2 = prepareGet(0, 0, namespace1, table1);
transaction1.get(get1_2);
Get get2_1 = prepareGet(0, 0, namespace1, table1);
Optional<Result> result2 = transaction2.get(get2_1);
assertThat(result2).isPresent();
int current2 = getBalance(result2.get());
Get get2_2 = prepareGet(0, 1, namespace2, table2);
transaction2.get(get2_2);
Put put1 = preparePut(0, 0, namespace1, table1).withValue(BALANCE, current1 + 1);
transaction1.put(put1);
Put put2 = preparePut(0, 1, namespace2, table2).withValue(BALANCE, current2 + 1);
transaction2.put(put2);
transaction1.commit();
Throwable thrown = catchThrowable(transaction2::commit);
// Assert
transaction = manager.start(Isolation.SERIALIZABLE, SerializableStrategy.EXTRA_READ);
result1 = transaction.get(get1_1);
assertThat(result1).isPresent();
assertThat(getBalance(result1.get())).isEqualTo(1);
result2 = transaction.get(get2_1);
assertThat(result2).isPresent();
assertThat(getBalance(result2.get())).isEqualTo(2);
assertThat(thrown).isInstanceOf(CommitConflictException.class);
}
use of com.scalar.db.api.Put in project scalardb by scalar-labs.
the class ConsensusCommitIntegrationTestBase method commit_WriteSkewWithScanOnExistingRecordsWithSerializableWithExtraRead_ShouldThrowCommitConflictException.
@Test
public void commit_WriteSkewWithScanOnExistingRecordsWithSerializableWithExtraRead_ShouldThrowCommitConflictException() throws CrudException, CommitException, UnknownTransactionStatusException {
// Arrange
List<Put> puts = Arrays.asList(preparePut(0, 0, namespace1, TABLE_1).withValue(BALANCE, 1), preparePut(0, 1, namespace1, TABLE_1).withValue(BALANCE, 1));
ConsensusCommit transaction = manager.start(Isolation.SERIALIZABLE, SerializableStrategy.EXTRA_READ);
transaction.put(puts);
transaction.commit();
// Act
ConsensusCommit transaction1 = manager.start(Isolation.SERIALIZABLE, SerializableStrategy.EXTRA_READ);
ConsensusCommit transaction2 = manager.start(Isolation.SERIALIZABLE, SerializableStrategy.EXTRA_READ);
List<Result> results1 = transaction1.scan(prepareScan(0, 0, 1, namespace1, TABLE_1));
int count1 = results1.size();
List<Result> results2 = transaction2.scan(prepareScan(0, 0, 1, namespace1, TABLE_1));
int count2 = results2.size();
Put put1 = preparePut(0, 0, namespace1, TABLE_1).withValue(BALANCE, count1 + 1);
transaction1.put(put1);
Put put2 = preparePut(0, 1, namespace1, TABLE_1).withValue(BALANCE, count2 + 1);
transaction2.put(put2);
Throwable thrown1 = catchThrowable(transaction1::commit);
Throwable thrown2 = catchThrowable(transaction2::commit);
// Assert
transaction = manager.start(Isolation.SERIALIZABLE, SerializableStrategy.EXTRA_READ);
Optional<Result> result1 = transaction.get(prepareGet(0, 0, namespace1, TABLE_1));
assertThat(result1).isPresent();
assertThat(getBalance(result1.get())).isEqualTo(3);
Optional<Result> result2 = transaction.get(prepareGet(0, 1, namespace1, TABLE_1));
assertThat(result2).isPresent();
assertThat(getBalance(result2.get())).isEqualTo(1);
assertThat(thrown1).doesNotThrowAnyException();
assertThat(thrown2).isInstanceOf(CommitConflictException.class);
}
use of com.scalar.db.api.Put in project scalardb by scalar-labs.
the class ConsensusCommitIntegrationTestBase method commit_WriteSkewWithScanOnNonExistingRecordsWithSerializableWithExtraWrite_ShouldThrowCommitConflictException.
@Test
public void commit_WriteSkewWithScanOnNonExistingRecordsWithSerializableWithExtraWrite_ShouldThrowCommitConflictException() throws CrudException {
// Arrange
// no records
// Act
ConsensusCommit transaction1 = manager.start(Isolation.SERIALIZABLE, SerializableStrategy.EXTRA_WRITE);
ConsensusCommit transaction2 = manager.start(Isolation.SERIALIZABLE, SerializableStrategy.EXTRA_WRITE);
List<Result> results1 = transaction1.scan(prepareScan(0, 0, 1, namespace1, TABLE_1));
int count1 = results1.size();
List<Result> results2 = transaction2.scan(prepareScan(0, 0, 1, namespace1, TABLE_1));
int count2 = results2.size();
Put put1 = preparePut(0, 0, namespace1, TABLE_1).withValue(BALANCE, count1 + 1);
transaction1.put(put1);
Put put2 = preparePut(0, 1, namespace1, TABLE_1).withValue(BALANCE, count2 + 1);
transaction2.put(put2);
Throwable thrown1 = catchThrowable(transaction1::commit);
Throwable thrown2 = catchThrowable(transaction2::commit);
// Assert
assertThat(results1).isEmpty();
assertThat(results2).isEmpty();
ConsensusCommit transaction = manager.start(Isolation.SERIALIZABLE, SerializableStrategy.EXTRA_WRITE);
Optional<Result> result1 = transaction.get(prepareGet(0, 0, namespace1, TABLE_1));
Optional<Result> result2 = transaction.get(prepareGet(0, 1, namespace1, TABLE_1));
assertThat(result1.isPresent()).isFalse();
assertThat(result2.isPresent()).isFalse();
assertThat(thrown1).isInstanceOf(CommitConflictException.class);
assertThat(thrown2).isInstanceOf(CommitConflictException.class);
}
use of com.scalar.db.api.Put in project scalardb by scalar-labs.
the class TwoPhaseConsensusCommitIntegrationTest method preparePut.
private Put preparePut(int id, int type, String table) {
Key partitionKey = new Key(ACCOUNT_ID, id);
Key clusteringKey = new Key(ACCOUNT_TYPE, type);
return new Put(partitionKey, clusteringKey).forNamespace(NAMESPACE).forTable(table).withConsistency(Consistency.LINEARIZABLE);
}
Aggregations