Interface IgniteTransactions


public interface IgniteTransactions
The Ignite Transactions facade that supports distributed transactions when working with tables. This interface provides the ability to perform transactions in both synchronous and asynchronous ways.

     // Synchronous transactional API to update the balance.
     client.transactions().runInTransaction(tx -> {
          Account account = accounts.get(tx, key);

          account.balance += 200.0d;

          accounts.put(tx, key, account);
      });
 
There is no need to call Transaction.commit() explicitly. The transaction is automatically committed when the closure is successfully executed.

     // Using asynchronous transactional API to update the balance.
     CompletableFuture<Void> fut = client.transactions().beginAsync().thenCompose(tx ->
             accounts
                 .getAsync(tx, key)
                 .thenCompose(account -> {
                     account.balance += 200.0d;

                     return accounts.putAsync(tx, key, account);
                 })
                 .thenCompose(ignored -> tx.commitAsync())
     );

     // Wait for completion.
     fut.join();
 
See Also:
  • Method Details

    • begin

      default Transaction begin()
      Begins a transaction.
      Returns:
      The started transaction.
    • begin

      Transaction begin(@Nullable @Nullable TransactionOptions options)
      Begins a transaction.
      Parameters:
      options - Transaction options.
      Returns:
      The started transaction.
    • beginAsync

      default CompletableFuture<Transaction> beginAsync()
      Begins a transaction.
      Returns:
      Started transaction.
    • beginAsync

      CompletableFuture<Transaction> beginAsync(@Nullable @Nullable TransactionOptions options)
      Begins an asynchronous transaction.
      Parameters:
      options - Transaction options.
      Returns:
      The future holding the started transaction.
    • runInTransaction

      default void runInTransaction(Consumer<Transaction> clo) throws TransactionException
      Executes a closure within a transaction.

      This method expects that all transaction operations are completed before the closure returns. The safest way to achieve that is to use synchronous table API.

      Take care then using the asynchronous operations inside the closure. For example, the following snippet is incorrect, because the last operation goes out of the scope of the closure unfinished:

       
       igniteTransactions.runInTransaction(tx -> {
           var key = Tuple.create().set("accountId", 1);
           Tuple acc = view.get(tx, key);
           view.upsertAsync(tx, Tuple.create().set("accountId", 1).set("balance", acc.longValue("balance") + 100));
       });
       
       

      The correct variant will be:

       
       igniteTransactions.runInTransaction(tx -> {
           view.getAsync(tx, Tuple.create().set("accountId", 1)).thenCompose(acc ->
               view.upsertAsync(tx, Tuple.create().set("accountId", 1).set("balance", acc.longValue("balance") + 100))).join();
       });
       
       

      If the closure is executed normally (no exceptions) the transaction is automatically committed. In a case of exception, the closure will be retried automatically within the transaction timeout, so it must be pure function. If the transaction timeout expires before the closure completes successfully and the transaction has been committed, the transaction is rolled back instead.
      The closure is retried only in cases of "expected" exceptions, like LockException, TimeoutException, exceptions related to the primary replica change, etc.

      Parameters:
      clo - The closure.
      Throws:
      TransactionException - If a transaction can't be finished successfully.
    • runInTransaction

      default void runInTransaction(Consumer<Transaction> clo, @Nullable @Nullable TransactionOptions options) throws TransactionException
      Executes a closure within a transaction.

      This method expects that all transaction operations are completed before the closure returns. The safest way to achieve that is to use synchronous table API.

      Take care then using the asynchronous operations inside the closure. For example, the following snippet is incorrect, because the last operation goes out of the scope of the closure unfinished:

       
       igniteTransactions.runInTransaction(tx -> {
           var key = Tuple.create().set("accountId", 1);
           Tuple acc = view.get(tx, key);
           view.upsertAsync(tx, Tuple.create().set("accountId", 1).set("balance", acc.longValue("balance") + 100));
       });
       
       

      The correct variant will be:

       
       igniteTransactions.runInTransaction(tx -> {
           view.getAsync(tx, Tuple.create().set("accountId", 1)).thenCompose(acc ->
               view.upsertAsync(tx, Tuple.create().set("accountId", 1).set("balance", acc.longValue("balance") + 100))).join();
       });
       
       

      If the closure is executed normally (no exceptions) the transaction is automatically committed. In a case of exception, the closure will be retried automatically within the transaction timeout, so it must be pure function. If the transaction timeout expires before the closure completes successfully and the transaction has been committed, the transaction is rolled back instead.
      The closure is retried only in cases of "expected" exceptions, like LockException, TimeoutException, exceptions related to the primary replica change, etc.

      Parameters:
      options - Transaction options.
      clo - The closure.
      Throws:
      TransactionException - If a transaction can't be finished successfully.
    • runInTransaction

      default <T> T runInTransaction(Function<Transaction,T> clo) throws TransactionException
      Executes a closure within a transaction and returns a result.

      This method expects that all transaction operations are completed before the closure returns. The safest way to achieve that is to use synchronous table API.

      Take care then using the asynchronous operations inside the closure. For example, the following snippet is incorrect, because the last operation goes out of the scope of the closure unfinished:

       
       igniteTransactions.runInTransaction(tx -> {
           var key = Tuple.create().set("accountId", 1);
           Tuple acc = view.get(tx, key);
           view.upsertAsync(tx, Tuple.create().set("accountId", 1).set("balance", acc.longValue("balance") + 100));
       });
       
       

      The correct variant will be:

       
       igniteTransactions.runInTransaction(tx -> {
           view.getAsync(tx, Tuple.create().set("accountId", 1)).thenCompose(acc ->
               view.upsertAsync(tx, Tuple.create().set("accountId", 1).set("balance", acc.longValue("balance") + 100))).join();
       });
       
       

      If the closure is executed normally (no exceptions) the transaction is automatically committed. In a case of exception, the closure will be retried automatically within the transaction timeout, so it must be pure function. If the transaction timeout expires before the closure completes successfully and the transaction has been committed, the transaction is rolled back instead.
      The closure is retried only in cases of "expected" exceptions, like LockException, TimeoutException, exceptions related to the primary replica change, etc.

      Type Parameters:
      T - Closure result type.
      Parameters:
      clo - Closure.
      Returns:
      Result.
      Throws:
      TransactionException - If a transaction can't be finished successfully.
    • runInTransaction

      default <T> T runInTransaction(Function<Transaction,T> clo, @Nullable @Nullable TransactionOptions options) throws TransactionException
      Executes a closure within a transaction and returns a result.

      This method expects that all transaction operations are completed before the closure returns. The safest way to achieve that is to use synchronous table API.

      Take care then using the asynchronous operations inside the closure. For example, the following snippet is incorrect, because the last operation goes out of the scope of the closure unfinished:

       
       igniteTransactions.runInTransaction(tx -> {
           var key = Tuple.create().set("accountId", 1);
           Tuple acc = view.get(tx, key);
           view.upsertAsync(tx, Tuple.create().set("accountId", 1).set("balance", acc.longValue("balance") + 100));
       });
       
       

      The correct variant will be:

       
       igniteTransactions.runInTransaction(tx -> {
           view.getAsync(tx, Tuple.create().set("accountId", 1)).thenCompose(acc ->
               view.upsertAsync(tx, Tuple.create().set("accountId", 1).set("balance", acc.longValue("balance") + 100))).join();
       });
       
       

      If the closure is executed normally (no exceptions) the transaction is automatically committed. In a case of exception, the closure will be retried automatically within the transaction timeout, so it must be pure function. If the transaction timeout expires before the closure completes successfully and the transaction has been committed, the transaction is rolled back instead.
      The closure is retried only in cases of "expected" exceptions, like LockException, TimeoutException, exceptions related to the primary replica change, etc.

      Type Parameters:
      T - Closure result type.
      Parameters:
      clo - The closure.
      options - Transaction options.
      Returns:
      The result.
      Throws:
      TransactionException - If a transaction can't be finished successfully.
    • runInTransactionAsync

      default <T> CompletableFuture<T> runInTransactionAsync(Function<Transaction,CompletableFuture<T>> clo)
      Executes a closure within a transaction asynchronously.

      A returned future must be the last in the asynchronous chain. This means all transaction operations happen before the future is completed.

      Consider the example:

       
           igniteTransactions.runInTransactionAsync(tx -> view.getAsync(tx, Tuple.create().set("accountId", 1)).thenCompose(
               acc -> view.upsertAsync(tx, Tuple.create().set("accountId", 1).set("balance", acc.longValue("balance") + 100))));
       
       

      If the asynchronous chain resulted with no exception, the commitAsync will be automatically called. In a case of exception, the closure will be retried automatically within the transaction timeout, so it must be pure function. If the transaction timeout expires before the closure completes successfully and the transaction has been committed, the transaction is rolled back instead.
      The closure is retried only in cases of "expected" exceptions, like LockException, TimeoutException, exceptions related to the primary replica change, etc.

      Type Parameters:
      T - Closure result type.
      Parameters:
      clo - The closure.
      Returns:
      The result.
    • runInTransactionAsync

      default <T> CompletableFuture<T> runInTransactionAsync(Function<Transaction,CompletableFuture<T>> clo, @Nullable @Nullable TransactionOptions options)
      Executes a closure within a transaction asynchronously.

      A returned future must be the last in the asynchronous chain. This means all transaction operations happen before the future is completed.

      Consider the example:

       
           igniteTransactions.runInTransactionAsync(tx -> view.getAsync(tx, Tuple.create().set("accountId", 1)).thenCompose(
               acc -> view.upsertAsync(tx, Tuple.create().set("accountId", 1).set("balance", acc.longValue("balance") + 100))));
       
       

      If the asynchronous chain resulted with no exception, the commitAsync will be automatically called. In a case of exception, the closure will be retried automatically within the transaction timeout, so it must be pure function. If the transaction timeout expires before the closure completes successfully and the transaction has been committed, the transaction is rolled back instead.
      The closure is retried only in cases of "expected" exceptions, like LockException, TimeoutException, exceptions related to the primary replica change, etc.

      Type Parameters:
      T - Closure result type.
      Parameters:
      clo - The closure.
      options - Transaction options.
      Returns:
      The result.