7.9 @Transactionalについて

XAトランザクション・プロトコルを使用するJavaアプリケーションは2つの異なる方法で構成できます。

  • トランザクション境界を明示的に定義する方法
  • @Transactional注釈を使用する方法

どの方法にも独自の利点があります。

@Transactional注釈

@Transactional注釈を使用する場合は、ビジネス・ロジックのみを指定します。トランザクション境界を定義する必要はありません。例外がある場合のみ、トランザクションはロールバックされます。他のすべてのシナリオでは、トランザクションはコミットされます。

次のコード・サンプルは、@Transactional注釈の使用方法を示しています。アプリケーション・ビジネス・ロジックを定義する既存のtransferメソッドに@Transactional注釈を付けます。transferメソッドは、参加側サービス1から金額を借方記入するwithdrawメソッドと、参加側サービス2に金額を貸方記入するdepositメソッドをコールします。この場合、アプリケーションのビジネス・ロジックのみを定義する必要があることに注意してください。

@Transactionalを使用したJAX-RSアプリケーションのサンプル・コード

import javax.transaction.Transactional;
...//some code
@Transactional(value = Transactional.TxType.REQUIRED)
transfer(){
    // code that is specific to the application's business logic
    // withdraw operation on participant service 1    
    // deposit operation on participant service 2
}

JAX-RSアプリケーションでの@Transactionalの使用の詳細は、https://docs.oracle.com/javaee/7/api/javax/transaction/Transactional.htmlを参照してください。

@Transactionalを使用したSpring RESTアプリケーションのサンプル・コード

import org.springframework.transaction.annotation.Transactional;
...//some code
  @Transactional(propagation = Propagation.REQUIRED)
  
transfer(){
    // code that is specific to the application's business logic
    // withdraw operation on participant service 1
    // deposit operation on participant service 2
    }

Spring RESTアプリケーションでの@Transactionalの使用の詳細は、https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Transactional.htmlを参照してください。

トランザクション境界の定義

トランザクション境界を定義するJAX-RSアプリケーションのサンプル・コード

トランザクション境界を定義するJAX-RSアプリケーションのサンプル・コード

トランザクションをコミットまたはロールバックする特定の条件を指定する場合は、トランザクション境界を定義できます。begin()およびcommit()またはrollback()メソッドを使用して、トランザクション境界を定義します。トランザクション境界の開始を定義するコードを指定し、トランザクションをコミットまたはロールバックするタイミングを決定するビジネス・ロジックも指定する必要があります。これにより、トランザクションがコミットまたはロールバックされるシナリオを柔軟に定義できます。

次のサンプルは、transferメソッドを示しており、これは参加側サービス1から金額を借方記入するwithdrawメソッドと、参加側サービス2に金額を貸方記入するdepositメソッドをコールします。この場合、トランザクション境界とアプリケーションのビジネス・ロジックのみを定義する必要があることに注意してください。

TrmUserTransactionオブジェクトを作成して処理します。

transfer() {
    //Application-specific business logic
    TrmUserTransaction transaction = new TrmUserTransaction();
    //Starts a transaction. This is where the transaction boundary begins.
    transaction.begin();
    // code that is specific to the application's business logic
    // withdraw operation on participant service 1    
    isWithdrawSuccessful = withdraw();
    if(!isWithdrawSuccessful){
        transaction.rollback();
    }
    // deposit operation on participant service 2
    isDepositSuccessful = deposit();
    if(!isDepositSuccessful){
        transaction.rollback();
    }
    transaction.commit();
    //When you commit or rollback a transaction, the transaction boundary ends.
    //Application-specific business logic
}

MicroTxUserTransactionServiceオブジェクトを作成して処理します。

// Autowire the MicroTx transaction service
@Autowired
MicroTxUserTransactionService microTxtransaction;

transfer() {
    try {
        //Starts a transaction. This is where the transaction boundary begins.
        microTxtransaction.begin();
        // code that is specific to the application's business logic
        // withdraw operation on participant service 1
        isWithdrawSuccessful = withdraw();
    
        if(!isWithdrawSuccessful){
            microTxtransaction.rollback();
        }
        // deposit operation on participant service 2
        isDepositSuccessful = deposit();
        if(!isDepositSuccessful){
            microTxtransaction.rollback();
        }
        microTxtransaction.commit();
        //When you commit or rollback a transaction, the transaction boundary ends.
        //Application-specific business logic
    } catch (Exception ex) {
        microTxtransaction.rollback();
        // Handle exception
    }
}

このガイドのすべてのコード例は、トランザクション境界を定義します。