Skip to content

Commit

Permalink
Allow directly executing CRUD operations with transaction managers (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
brfrn169 authored May 27, 2024
1 parent 5adae62 commit ab818c6
Show file tree
Hide file tree
Showing 25 changed files with 2,953 additions and 405 deletions.
134 changes: 134 additions & 0 deletions core/src/main/java/com/scalar/db/api/CrudOperable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package com.scalar.db.api;

import com.scalar.db.exception.transaction.CommitConflictException;
import com.scalar.db.exception.transaction.CrudConflictException;
import com.scalar.db.exception.transaction.PreparationConflictException;
import com.scalar.db.exception.transaction.TransactionException;
import com.scalar.db.exception.transaction.UnsatisfiedConditionException;
import java.util.List;
import java.util.Optional;

/**
* An interface for transactional CRUD operations. Note that the LINEARIZABLE consistency level is
* always used in transactional CRUD operations, so {@link Consistency} specified for CRUD
* operations is ignored.
*/
public interface CrudOperable<E extends TransactionException> {

/**
* Retrieves a result from the storage through a transaction with the specified {@link Get}
* command with a primary key and returns the result.
*
* @param get a {@code Get} command
* @return an {@code Optional} with the returned result
* @throws E if the transaction CRUD operation fails
*/
Optional<Result> get(Get get) throws E;

/**
* Retrieves results from the storage through a transaction with the specified {@link Scan}
* command with a partition key and returns a list of {@link Result}. Results can be filtered by
* specifying a range of clustering keys.
*
* @param scan a {@code Scan} command
* @return a list of {@link Result}
* @throws E if the transaction CRUD operation fails
*/
List<Result> scan(Scan scan) throws E;

/**
* Inserts an entry into or updates an entry in the underlying storage through a transaction with
* the specified {@link Put} command. If a condition is specified in the {@link Put} command, and
* if the condition is not satisfied or the entry does not exist, it throws {@link
* UnsatisfiedConditionException}.
*
* @param put a {@code Put} command
* @throws E if the transaction CRUD operation fails
* @deprecated As of release 3.13.0. Will be removed in release 5.0.0.
*/
@Deprecated
void put(Put put) throws E;

/**
* Inserts multiple entries into or updates multiple entries in the underlying storage through a
* transaction with the specified list of {@link Put} commands. If a condition is specified in the
* {@link Put} command, and if the condition is not satisfied or the entry does not exist, it
* throws {@link UnsatisfiedConditionException}.
*
* @param puts a list of {@code Put} commands
* @throws E if the transaction CRUD operation fails
* @deprecated As of release 3.13.0. Will be removed in release 5.0.0. Use {@link #mutate(List)}
* instead.
*/
@Deprecated
void put(List<Put> puts) throws E;

/**
* Inserts an entry into the underlying storage through a transaction with the specified {@link
* Insert} command. If the entry already exists, a conflict error occurs. Note that the location
* where the conflict error is thrown depends on the implementation of the transaction manager.
* This method may throw {@link CrudConflictException}. Alternatively, {@link
* DistributedTransaction#commit()} or {@link TwoPhaseCommitTransaction#prepare()} may throw
* {@link CommitConflictException} or {@link PreparationConflictException} respectively in case of
* a conflict error.
*
* @param insert a {@code Insert} command
* @throws E if the transaction CRUD operation fails
*/
void insert(Insert insert) throws E;

/**
* Inserts an entry into or updates an entry in the underlying storage through a transaction with
* the specified {@link Upsert} command. If the entry already exists, it is updated; otherwise, it
* is inserted.
*
* @param upsert a {@code Upsert} command
* @throws E if the transaction CRUD operation fails
*/
void upsert(Upsert upsert) throws E;

/**
* Updates an entry in the underlying storage through a transaction with the specified {@link
* Update} command. If the entry does not exist, it does nothing. If a condition is specified in
* the {@link Update} command, and if the condition is not satisfied or the entry does not exist,
* it throws {@link UnsatisfiedConditionException}.
*
* @param update an {@code Update} command
* @throws E if the transaction CRUD operation fails
*/
void update(Update update) throws E;

/**
* Deletes an entry from the underlying storage through a transaction with the specified {@link
* Delete} command. If a condition is specified in the {@link Delete} command, and if the
* condition is not satisfied or the entry does not exist, it throws {@link
* UnsatisfiedConditionException}.
*
* @param delete a {@code Delete} command
* @throws E if the transaction CRUD operation fails
*/
void delete(Delete delete) throws E;

/**
* Deletes entries from the underlying storage through a transaction with the specified list of
* {@link Delete} commands. If a condition is specified in the {@link Delete} command, and if the
* condition is not satisfied or the entry does not exist, it throws {@link
* UnsatisfiedConditionException}.
*
* @param deletes a list of {@code Delete} commands
* @throws E if the transaction CRUD operation fails
* @deprecated As of release 3.13.0. Will be removed in release 5.0.0. Use {@link #mutate(List)}
* instead.
*/
@Deprecated
void delete(List<Delete> deletes) throws E;

/**
* Mutates entries of the underlying storage through a transaction with the specified list of
* {@link Mutation} commands.
*
* @param mutations a list of {@code Mutation} commands
* @throws E if the transaction CRUD operation fails
*/
void mutate(List<? extends Mutation> mutations) throws E;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import com.scalar.db.exception.transaction.TransactionNotFoundException;
import java.util.Optional;

public interface DistributedTransactionManager {
public interface DistributedTransactionManager
extends TransactionManagerCrudOperable, AutoCloseable {

/**
* Sets the specified namespace and the table name as default values in the instance.
Expand Down Expand Up @@ -251,5 +252,6 @@ default TransactionState abort(String txId) throws TransactionException {
* Closes connections to the cluster. The connections are shared among multiple services such as
* StorageService and TransactionService, thus this should only be used when closing applications.
*/
@Override
void close();
}
107 changes: 36 additions & 71 deletions core/src/main/java/com/scalar/db/api/TransactionCrudOperable.java
Original file line number Diff line number Diff line change
@@ -1,56 +1,41 @@
package com.scalar.db.api;

import com.scalar.db.exception.transaction.CommitConflictException;
import com.scalar.db.exception.transaction.CrudConflictException;
import com.scalar.db.exception.transaction.CrudException;
import com.scalar.db.exception.transaction.PreparationConflictException;
import com.scalar.db.exception.transaction.UnsatisfiedConditionException;
import java.util.List;
import java.util.Optional;

/**
* An interface for transactional CRUD operations. Note that the LINEARIZABLE consistency level is
* always used in transactional CRUD operations, so {@link Consistency} specified for CRUD
* operations is ignored.
*/
public interface TransactionCrudOperable {
/** An interface for transactional CRUD operations for transactions. */
public interface TransactionCrudOperable extends CrudOperable<CrudException> {

/**
* Retrieves a result from the storage through a transaction with the specified {@link Get}
* command with a primary key and returns the result.
* {@inheritDoc}
*
* @param get a {@code Get} command
* @return an {@code Optional} with the returned result
* @throws CrudConflictException if the transaction CRUD operation fails due to transient faults
* (e.g., a conflict error). You can retry the transaction from the beginning
* @throws CrudException if the transaction CRUD operation fails due to transient or nontransient
* faults. You can try retrying the transaction from the beginning, but the transaction may
* still fail if the cause is nontranient
*/
@Override
Optional<Result> get(Get get) throws CrudConflictException, CrudException;

/**
* Retrieves results from the storage through a transaction with the specified {@link Scan}
* command with a partition key and returns a list of {@link Result}. Results can be filtered by
* specifying a range of clustering keys.
* {@inheritDoc}
*
* @param scan a {@code Scan} command
* @return a list of {@link Result}
* @throws CrudConflictException if the transaction CRUD operation fails due to transient faults
* (e.g., a conflict error). You can retry the transaction from the beginning
* @throws CrudException if the transaction CRUD operation fails due to transient or nontransient
* faults. You can try retrying the transaction from the beginning, but the transaction may
* still fail if the cause is nontranient
*/
@Override
List<Result> scan(Scan scan) throws CrudConflictException, CrudException;

/**
* Inserts an entry into or updates an entry in the underlying storage through a transaction with
* the specified {@link Put} command. If a condition is specified in the {@link Put} command, and
* if the condition is not satisfied or the entry does not exist, it throws {@link
* UnsatisfiedConditionException}.
* {@inheritDoc}
*
* @param put a {@code Put} command
* @throws CrudConflictException if the transaction CRUD operation fails due to transient faults
* (e.g., a conflict error). You can retry the transaction from the beginning
* @throws CrudException if the transaction CRUD operation fails due to transient or nontransient
Expand All @@ -61,15 +46,12 @@ public interface TransactionCrudOperable {
* @deprecated As of release 3.13.0. Will be removed in release 5.0.0.
*/
@Deprecated
@Override
void put(Put put) throws CrudConflictException, CrudException, UnsatisfiedConditionException;

/**
* Inserts multiple entries into or updates multiple entries in the underlying storage through a
* transaction with the specified list of {@link Put} commands. If a condition is specified in the
* {@link Put} command, and if the condition is not satisfied or the entry does not exist, it
* throws {@link UnsatisfiedConditionException}.
* {@inheritDoc}
*
* @param puts a list of {@code Put} commands
* @throws CrudConflictException if the transaction CRUD operation fails due to transient faults
* (e.g., a conflict error). You can retry the transaction from the beginning
* @throws CrudException if the transaction CRUD operation fails due to transient or nontransient
Expand All @@ -81,103 +63,85 @@ public interface TransactionCrudOperable {
* instead.
*/
@Deprecated
@Override
void put(List<Put> puts)
throws CrudConflictException, CrudException, UnsatisfiedConditionException;

/**
* Deletes an entry from the underlying storage through a transaction with the specified {@link
* Delete} command. If a condition is specified in the {@link Delete} command, and if the
* condition is not satisfied or the entry does not exist, it throws {@link
* UnsatisfiedConditionException}.
* {@inheritDoc}
*
* @param delete a {@code Delete} command
* @throws CrudConflictException if the transaction CRUD operation fails due to transient faults
* (e.g., a conflict error). You can retry the transaction from the beginning
* @throws CrudException if the transaction CRUD operation fails due to transient or nontransient
* faults. You can try retrying the transaction from the beginning, but the transaction may
* still fail if the cause is nontranient
* @throws UnsatisfiedConditionException if a condition is specified, and if the condition is not
* satisfied or the entry does not exist
*/
void delete(Delete delete)
throws CrudConflictException, CrudException, UnsatisfiedConditionException;
@Override
void insert(Insert insert) throws CrudConflictException, CrudException;

/**
* Deletes entries from the underlying storage through a transaction with the specified list of
* {@link Delete} commands. If a condition is specified in the {@link Delete} command, and if the
* condition is not satisfied or the entry does not exist, it throws {@link
* UnsatisfiedConditionException}.
* {@inheritDoc}
*
* @param deletes a list of {@code Delete} commands
* @throws CrudConflictException if the transaction CRUD operation fails due to transient faults
* (e.g., a conflict error). You can retry the transaction from the beginning
* @throws CrudException if the transaction CRUD operation fails due to transient or nontransient
* faults. You can try retrying the transaction from the beginning, but the transaction may
* still fail if the cause is nontranient
* @throws UnsatisfiedConditionException if a condition is specified, and if the condition is not
* satisfied or the entry does not exist
* @deprecated As of release 3.13.0. Will be removed in release 5.0.0. Use {@link #mutate(List)}
* instead.
*/
@Deprecated
void delete(List<Delete> deletes)
throws CrudConflictException, CrudException, UnsatisfiedConditionException;
@Override
void upsert(Upsert upsert) throws CrudConflictException, CrudException;

/**
* Inserts an entry into the underlying storage through a transaction with the specified {@link
* Insert} command. If the entry already exists, a conflict error occurs. Note that the location
* where the conflict error is thrown depends on the implementation of the transaction manager.
* This method may throw {@link CrudConflictException}. Alternatively, {@link
* DistributedTransaction#commit()} or {@link TwoPhaseCommitTransaction#prepare()} may throw
* {@link CommitConflictException} or {@link PreparationConflictException} respectively in case of
* a conflict error.
* {@inheritDoc}
*
* @param insert a {@code Insert} command
* @throws CrudConflictException if the transaction CRUD operation fails due to transient faults
* (e.g., a conflict error). You can retry the transaction from the beginning
* @throws CrudException if the transaction CRUD operation fails due to transient or nontransient
* faults. You can try retrying the transaction from the beginning, but the transaction may
* still fail if the cause is nontranient
* @throws UnsatisfiedConditionException if a condition is specified, and if the condition is not
* satisfied or the entry does not exist
*/
void insert(Insert insert) throws CrudConflictException, CrudException;
@Override
void update(Update update)
throws CrudConflictException, CrudException, UnsatisfiedConditionException;

/**
* Inserts an entry into or updates an entry in the underlying storage through a transaction with
* the specified {@link Upsert} command. If the entry already exists, it is updated; otherwise, it
* is inserted.
* {@inheritDoc}
*
* @param upsert a {@code Upsert} command
* @throws CrudConflictException if the transaction CRUD operation fails due to transient faults
* (e.g., a conflict error). You can retry the transaction from the beginning
* @throws CrudException if the transaction CRUD operation fails due to transient or nontransient
* faults. You can try retrying the transaction from the beginning, but the transaction may
* still fail if the cause is nontranient
* @throws UnsatisfiedConditionException if a condition is specified, and if the condition is not
* satisfied or the entry does not exist
*/
void upsert(Upsert upsert) throws CrudConflictException, CrudException;
@Override
void delete(Delete delete)
throws CrudConflictException, CrudException, UnsatisfiedConditionException;

/**
* Updates an entry in the underlying storage through a transaction with the specified {@link
* Update} command. If the entry does not exist, it does nothing. If a condition is specified in
* the {@link Update} command, and if the condition is not satisfied or the entry does not exist,
* it throws {@link UnsatisfiedConditionException}.
* {@inheritDoc}
*
* @param update an {@code Update} command
* @throws CrudConflictException if the transaction CRUD operation fails due to transient faults
* (e.g., a conflict error). You can retry the transaction from the beginning
* @throws CrudException if the transaction CRUD operation fails due to transient or nontransient
* faults. You can try retrying the transaction from the beginning, but the transaction may
* still fail if the cause is nontranient
* @throws UnsatisfiedConditionException if a condition is specified, and if the condition is not
* satisfied or the entry does not exist
* @deprecated As of release 3.13.0. Will be removed in release 5.0.0. Use {@link #mutate(List)}
* instead.
*/
void update(Update update)
@Deprecated
@Override
void delete(List<Delete> deletes)
throws CrudConflictException, CrudException, UnsatisfiedConditionException;

/**
* Mutates entries of the underlying storage through a transaction with the specified list of
* {@link Mutation} commands.
* {@inheritDoc}
*
* @param mutations a list of {@code Mutation} commands
* @throws CrudConflictException if the transaction CRUD operation fails due to transient faults
* (e.g., a conflict error). You can retry the transaction from the beginning
* @throws CrudException if the transaction CRUD operation fails due to transient or nontransient
Expand All @@ -187,6 +151,7 @@ void update(Update update)
* Delete}, or {@link Update} command, and if the condition is not satisfied or the entry does
* not exist
*/
@Override
void mutate(List<? extends Mutation> mutations)
throws CrudConflictException, CrudException, UnsatisfiedConditionException;
}
Loading

0 comments on commit ab818c6

Please sign in to comment.