use of com.scalar.db.transaction.rpc.GrpcTwoPhaseCommitTransaction in project scalardb by scalar-labs.
the class TwoPhaseCommitTransactionServiceWithTwoPhaseConsensusCommitIntegrationTest method get_GetGivenForCommittedRecord_ShouldReturnRecord.
@Test
public void get_GetGivenForCommittedRecord_ShouldReturnRecord() throws TransactionException {
// Arrange
populate(TABLE_1);
GrpcTwoPhaseCommitTransaction transaction = manager.start();
// Act
Optional<Result> result = transaction.get(prepareGet(0, 0, TABLE_1));
transaction.prepare();
transaction.commit();
// Assert
assertThat(result.isPresent()).isTrue();
assertThat(getAccountId(result.get())).isEqualTo(0);
assertThat(getAccountType(result.get())).isEqualTo(0);
assertThat(getBalance(result.get())).isEqualTo(INITIAL_BALANCE);
}
use of com.scalar.db.transaction.rpc.GrpcTwoPhaseCommitTransaction in project scalardb by scalar-labs.
the class TwoPhaseCommitTransactionServiceWithTwoPhaseConsensusCommitIntegrationTest method commit_ConflictingPutsGivenForNonExisting_ShouldCommitOneAndAbortTheOther.
@Test
public void commit_ConflictingPutsGivenForNonExisting_ShouldCommitOneAndAbortTheOther() throws TransactionException {
// Arrange
int expected = INITIAL_BALANCE;
int fromId = 0;
int fromType = 0;
int toId = 1;
int toType = 0;
int anotherFromId = toId;
int anotherFromType = toType;
int anotherToId = 2;
int anotherToType = 0;
GrpcTwoPhaseCommitTransaction fromTx = manager.start();
GrpcTwoPhaseCommitTransaction toTx = manager.join(fromTx.getId());
fromTx.put(preparePut(fromId, fromType, TABLE_1).withValue(BALANCE, expected));
toTx.put(preparePut(toId, toType, TABLE_2).withValue(BALANCE, expected));
// Act Assert
assertThatCode(() -> {
GrpcTwoPhaseCommitTransaction anotherFromTx = manager.start();
GrpcTwoPhaseCommitTransaction anotherToTx = manager.join(anotherFromTx.getId());
anotherFromTx.put(preparePut(anotherFromId, anotherFromType, TABLE_2).withValue(BALANCE, expected));
anotherToTx.put(preparePut(anotherToId, anotherToType, TABLE_1).withValue(BALANCE, expected));
anotherFromTx.prepare();
anotherToTx.prepare();
anotherFromTx.commit();
anotherToTx.commit();
}).doesNotThrowAnyException();
assertThatThrownBy(() -> {
fromTx.prepare();
toTx.prepare();
}).isInstanceOf(PreparationException.class);
fromTx.rollback();
toTx.rollback();
// Assert
GrpcTwoPhaseCommitTransaction another = manager.start();
Optional<Result> result = another.get(prepareGet(fromId, fromType, TABLE_1));
assertThat(result).isNotPresent();
result = another.get(prepareGet(toId, toType, TABLE_2));
assertThat(result).isPresent();
assertThat(getBalance(result.get())).isEqualTo(expected);
result = another.get(prepareGet(anotherToId, anotherToType, TABLE_1));
assertThat(result).isPresent();
assertThat(getBalance(result.get())).isEqualTo(expected);
another.prepare();
another.commit();
}
use of com.scalar.db.transaction.rpc.GrpcTwoPhaseCommitTransaction in project scalardb by scalar-labs.
the class TwoPhaseCommitTransactionServiceWithTwoPhaseConsensusCommitIntegrationTest method commit_WriteSkewOnExistingRecordsWithSnapshot_ShouldProduceNonSerializableResult.
@Test
public void commit_WriteSkewOnExistingRecordsWithSnapshot_ShouldProduceNonSerializableResult() throws TransactionException {
// Arrange
GrpcTwoPhaseCommitTransaction transaction = manager.start();
transaction.put(preparePut(0, 0, TABLE_1).withValue(BALANCE, 1));
transaction.put(preparePut(1, 0, TABLE_2).withValue(BALANCE, 1));
transaction.prepare();
transaction.commit();
// Act
GrpcTwoPhaseCommitTransaction tx1Sub1 = manager.start();
GrpcTwoPhaseCommitTransaction tx1Sub2 = manager.join(tx1Sub1.getId());
Optional<Result> result = tx1Sub2.get(prepareGet(1, 0, TABLE_2));
assertThat(result).isPresent();
int current1 = getBalance(result.get());
tx1Sub1.get(prepareGet(0, 0, TABLE_1));
tx1Sub1.put(preparePut(0, 0, TABLE_1).withValue(BALANCE, current1 + 1));
GrpcTwoPhaseCommitTransaction tx2Sub1 = manager.start();
GrpcTwoPhaseCommitTransaction tx2Sub2 = manager.join(tx2Sub1.getId());
result = tx2Sub1.get(prepareGet(0, 0, TABLE_1));
assertThat(result).isPresent();
int current2 = getBalance(result.get());
tx2Sub2.get(prepareGet(1, 0, TABLE_2));
tx2Sub2.put(preparePut(1, 0, TABLE_2).withValue(BALANCE, current2 + 1));
tx1Sub1.prepare();
tx1Sub2.prepare();
tx1Sub1.commit();
tx1Sub2.commit();
tx2Sub1.prepare();
tx2Sub2.prepare();
tx2Sub1.commit();
tx2Sub2.commit();
// Assert
transaction = manager.start();
// the results can not be produced by executing the transactions serially
result = transaction.get(prepareGet(0, 0, TABLE_1));
assertThat(result).isPresent();
assertThat(getBalance(result.get())).isEqualTo(current1 + 1);
result = transaction.get(prepareGet(1, 0, TABLE_2));
assertThat(result).isPresent();
assertThat(getBalance(result.get())).isEqualTo(current2 + 1);
transaction.prepare();
transaction.commit();
}
use of com.scalar.db.transaction.rpc.GrpcTwoPhaseCommitTransaction in project scalardb by scalar-labs.
the class TwoPhaseCommitTransactionServiceWithTwoPhaseConsensusCommitWithExtraReadIntegrationTest method commit_WriteSkewOnExistingRecordsWithSerializableWithExtraRead_OneShouldCommitTheOtherShouldThrowValidationException.
@Test
public void commit_WriteSkewOnExistingRecordsWithSerializableWithExtraRead_OneShouldCommitTheOtherShouldThrowValidationException() throws TransactionException {
// Arrange
GrpcTwoPhaseCommitTransaction transaction = manager.start();
transaction.put(preparePut(0, 0, TABLE_1).withValue(BALANCE, 1));
transaction.put(preparePut(1, 0, TABLE_2).withValue(BALANCE, 1));
transaction.prepare();
transaction.validate();
transaction.commit();
// Act Assert
GrpcTwoPhaseCommitTransaction tx1Sub1 = manager.start();
GrpcTwoPhaseCommitTransaction tx1Sub2 = manager.join(tx1Sub1.getId());
Optional<Result> result = tx1Sub2.get(prepareGet(1, 0, TABLE_2));
assertThat(result).isPresent();
int current1 = getBalance(result.get());
tx1Sub1.get(prepareGet(0, 0, TABLE_1));
tx1Sub1.put(preparePut(0, 0, TABLE_1).withValue(BALANCE, current1 + 1));
GrpcTwoPhaseCommitTransaction tx2Sub1 = manager.start();
GrpcTwoPhaseCommitTransaction tx2Sub2 = manager.join(tx2Sub1.getId());
result = tx2Sub1.get(prepareGet(0, 0, TABLE_1));
assertThat(result).isPresent();
int current2 = getBalance(result.get());
tx2Sub2.get(prepareGet(1, 0, TABLE_2));
tx2Sub2.put(preparePut(1, 0, TABLE_2).withValue(BALANCE, current2 + 1));
tx1Sub1.prepare();
tx1Sub2.prepare();
tx1Sub1.validate();
tx1Sub2.validate();
tx1Sub1.commit();
tx1Sub2.commit();
tx2Sub1.prepare();
tx2Sub2.prepare();
assertThatThrownBy(() -> {
tx2Sub1.validate();
tx2Sub2.validate();
}).isInstanceOf(ValidationException.class);
tx2Sub1.rollback();
tx2Sub2.rollback();
// Assert
transaction = manager.start();
result = transaction.get(prepareGet(0, 0, TABLE_1));
assertThat(result).isPresent();
assertThat(getBalance(result.get())).isEqualTo(current1 + 1);
result = transaction.get(prepareGet(1, 0, TABLE_2));
assertThat(result).isPresent();
assertThat(getBalance(result.get())).isEqualTo(current2);
transaction.prepare();
transaction.validate();
transaction.commit();
}
use of com.scalar.db.transaction.rpc.GrpcTwoPhaseCommitTransaction in project scalardb by scalar-labs.
the class TwoPhaseCommitTransactionServiceWithTwoPhaseConsensusCommitWithExtraReadIntegrationTest method commit_WriteSkewWithScanOnExistingRecordsWithSerializableWithExtraRead_ShouldThrowValidationException.
@Test
public void commit_WriteSkewWithScanOnExistingRecordsWithSerializableWithExtraRead_ShouldThrowValidationException() throws TransactionException {
// Arrange
GrpcTwoPhaseCommitTransaction transaction = manager.start();
transaction.put(preparePut(0, 0, TABLE_1).withValue(BALANCE, 1));
transaction.put(preparePut(0, 1, TABLE_1).withValue(BALANCE, 1));
transaction.prepare();
transaction.validate();
transaction.commit();
// Act Assert
GrpcTwoPhaseCommitTransaction transaction1 = manager.start();
List<Result> results = transaction1.scan(prepareScan(0, 0, 1, TABLE_1));
assertThat(results.size()).isEqualTo(2);
int count1 = results.size();
transaction1.put(preparePut(0, 0, TABLE_1).withValue(BALANCE, count1 + 1));
GrpcTwoPhaseCommitTransaction transaction2 = manager.start();
results = transaction2.scan(prepareScan(0, 0, 1, TABLE_1));
assertThat(results.size()).isEqualTo(2);
int count2 = results.size();
transaction2.put(preparePut(0, 1, TABLE_1).withValue(BALANCE, count2 + 1));
assertThatCode(() -> {
transaction1.prepare();
transaction1.validate();
transaction1.commit();
}).doesNotThrowAnyException();
transaction2.prepare();
assertThatThrownBy(transaction2::validate).isInstanceOf(ValidationException.class);
transaction2.rollback();
// Assert
transaction = manager.start();
Optional<Result> result = transaction.get(prepareGet(0, 0, TABLE_1));
assertThat(result).isPresent();
assertThat(getBalance(result.get())).isEqualTo(count1 + 1);
result = transaction.get(prepareGet(0, 1, TABLE_1));
assertThat(result).isPresent();
assertThat(getBalance(result.get())).isEqualTo(1);
transaction.prepare();
transaction.validate();
transaction.commit();
}
Aggregations