use of com.scalar.db.exception.storage.RetriableExecutionException in project scalardb by scalar-labs.
the class PutStatementHandler method handle.
@Nonnull
@Override
public List<Map<String, AttributeValue>> handle(Operation operation) throws ExecutionException {
checkArgument(operation, Put.class);
Put put = (Put) operation;
TableMetadata tableMetadata = metadataManager.getTableMetadata(operation);
try {
execute(put, tableMetadata);
} catch (ConditionalCheckFailedException e) {
throw new NoMutationException("no mutation was applied.", e);
} catch (TransactionConflictException e) {
throw new RetriableExecutionException(e.getMessage(), e);
} catch (DynamoDbException e) {
throw new ExecutionException(e.getMessage(), e);
}
return Collections.emptyList();
}
use of com.scalar.db.exception.storage.RetriableExecutionException in project scalardb by scalar-labs.
the class BatchHandler method handle.
/**
* Execute the specified list of {@link Mutation}s in batch. All the {@link Mutation}s in the list
* must be for the same partition.
*
* @param mutations a list of {@code Mutation}s to execute
* @throws NoMutationException if at least one of conditional {@code Mutation}s failed because it
* didn't meet the condition
*/
public void handle(List<? extends Mutation> mutations) throws ExecutionException {
if (mutations.size() > 25) {
throw new IllegalArgumentException("DynamoDB cannot batch more than 25 mutations at once.");
}
TableMetadata tableMetadata = metadataManager.getTableMetadata(mutations.get(0));
TransactWriteItemsRequest.Builder builder = TransactWriteItemsRequest.builder();
List<TransactWriteItem> transactItems = new ArrayList<>();
mutations.forEach(m -> transactItems.add(makeWriteItem(m, tableMetadata)));
builder.transactItems(transactItems);
try {
client.transactWriteItems(builder.build());
} catch (TransactionCanceledException e) {
boolean allReasonsAreTransactionConflicts = true;
for (CancellationReason reason : e.cancellationReasons()) {
if (reason.code().equals("ConditionalCheckFailed")) {
throw new NoMutationException("no mutation was applied.", e);
}
if (!reason.code().equals("TransactionConflict") && !reason.code().equals("None")) {
allReasonsAreTransactionConflicts = false;
}
}
if (allReasonsAreTransactionConflicts) {
// RetriableExecutionException
throw new RetriableExecutionException(e.getMessage(), e);
}
throw new ExecutionException(e.getMessage(), e);
} catch (DynamoDbException e) {
throw new ExecutionException(e.getMessage(), e);
}
}
use of com.scalar.db.exception.storage.RetriableExecutionException in project scalardb by scalar-labs.
the class BatchHandler method throwException.
private void throwException(CosmosException exception) throws ExecutionException {
LOGGER.error(exception.getMessage(), exception);
int statusCode = exception.getSubStatusCode();
if (statusCode == CosmosErrorCode.PRECONDITION_FAILED.get()) {
throw new NoMutationException("no mutation was applied.");
} else if (statusCode == CosmosErrorCode.RETRY_WITH.get()) {
throw new RetriableExecutionException(exception.getMessage(), exception);
}
throw new ExecutionException(exception.getMessage(), exception);
}
use of com.scalar.db.exception.storage.RetriableExecutionException in project scalardb by scalar-labs.
the class MutateStatementHandler method handle.
/**
* Executes the specified {@link Mutation} {@link Operation}
*
* @param operation {@link Mutation} operation
* @return a {@code ResultSet}
* @throws RetriableExecutionException if the execution failed, but it can be retriable
* @throws ReadRepairableExecutionException if the execution partially failed, which can be
* repaired by a following read
*/
@Override
@Nonnull
public ResultSet handle(Operation operation) throws ExecutionException {
try {
ResultSet results = handleInternal(operation);
Mutation mutation = (Mutation) operation;
if (mutation.getCondition().isPresent() && !results.one().getBool(0)) {
throw new NoMutationException("no mutation was applied.");
}
return results;
} catch (WriteTimeoutException e) {
LOGGER.warn("write timeout happened during mutate operation.", e);
if (e.getWriteType() == WriteType.CAS) {
// retry needs to be done if applications need to do the operation exactly
throw new RetriableExecutionException("paxos phase in CAS operation failed.", e);
} else if (e.getWriteType() == WriteType.SIMPLE) {
Mutation mutation = (Mutation) operation;
if (mutation.getCondition().isPresent()) {
// learn phase needs to be repaired (by re-reading)
throw new ReadRepairableExecutionException("learn phase in CAS operation failed.", e);
} else {
// retry needs to be done if applications need to do the operation exactly
throw new RetriableExecutionException("simple write operation failed.", e);
}
} else {
throw new ExecutionException("something wrong because it is neither CAS nor SIMPLE", e);
}
} catch (RuntimeException e) {
LOGGER.warn(e.getMessage(), e);
throw new RetriableExecutionException(e.getMessage(), e);
}
}
use of com.scalar.db.exception.storage.RetriableExecutionException in project scalardb by scalar-labs.
the class JdbcDatabase method mutate.
@Override
public void mutate(List<? extends Mutation> mutations) throws ExecutionException {
if (mutations.size() == 1) {
Mutation mutation = mutations.get(0);
if (mutation instanceof Put) {
put((Put) mutation);
} else if (mutation instanceof Delete) {
delete((Delete) mutation);
}
return;
}
mutations = copyAndSetTargetToIfNot(mutations);
Connection connection = null;
try {
connection = dataSource.getConnection();
connection.setAutoCommit(false);
} catch (SQLException e) {
close(connection);
throw new ExecutionException("mutate operation failed", e);
}
try {
if (!jdbcService.mutate(mutations, connection)) {
try {
connection.rollback();
} catch (SQLException e) {
throw new ExecutionException("failed to rollback", e);
}
throw new NoMutationException("no mutation was applied");
} else {
connection.commit();
}
} catch (SQLException e) {
try {
connection.rollback();
} catch (SQLException sqlException) {
throw new ExecutionException("failed to rollback", sqlException);
}
if (JdbcUtils.isConflictError(e, rdbEngine)) {
// conflicts can happen. Throw RetriableExecutionException in that case.
throw new RetriableExecutionException("conflict happened in a mutate operation", e);
}
throw new ExecutionException("mutate operation failed", e);
} finally {
close(connection);
}
}
Aggregations