7.10.2 トランザクション・イニシエータとしてのSpring Bootアプリケーションの構成

トランザクション・イニシエータ・サービスは、トランザクションを開始します。トランザクション・イニシエータ・サービスは、アプリケーションのビジネス・ロジックに基づいて、トランザクションの開始のみ、またはトランザクションの開始とトランザクションへの参加を行うことができます。

開始する前に、アプリケーションがトランザクションを開始するだけか、トランザクションを開始して参加するのかを確認します。2つのシナリオでは要件が若干異なるため、それに応じてアプリケーションを構成します。

2つのシナリオを検討して、アプリケーションがトランザクションを開始するだけか、トランザクションにも参加するかを理解します。
  • シナリオ1: 銀行振込アプリケーションによって、ある部門から別の部門に送金します。この場合、振込アプリケーションはトランザクションを開始するだけで、トランザクションには参加しません。振込アプリケーションは、トランザクションを完了するためにビジネス・ロジックに基づいて様々なサービスをコールします。データベース・インスタンスは、振込アプリケーションにアタッチされる場合とアタッチされない場合があります。
  • シナリオ2: 銀行振込アプリケーションによって、ある部門から別の部門に送金します。振込アプリケーションは、トランザクションごとに手数料として1%を請求します。この場合、振込アプリケーションはトランザクションを開始して参加します。データベース・インスタンスは、トランザクション情報を保存するために振込アプリケーションにアタッチされる必要があります。
Spring RESTまたはJAX-RSを使用してSpring Boot 3.xアプリケーションをトランザクション・イニシエータとして構成するには:
  1. MicroTxライブラリのプロパティ値を指定します。「Spring Bootアプリケーションのライブラリ・プロパティの構成」を参照してください。
  2. MicroTxライブラリ・ファイルをSpring Boot 3.xアプリケーションのpom.xmlファイルにmaven依存関係として含めます。次のサンプル・コードは24.4リリース用です。使用するリリース・バージョンに基づいて、正しいバージョンを指定してください。Spring Boot 3.xアプリケーションは、Java 17で動作します。
    • JDBCアプリケーションでは、microtx-spring-boot-starterファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter</artifactId>
           <version>24.4</version>
      </dependency>
    • HibernateがJPAプロバイダの場合は、microtx-spring-boot-starterおよびmicrotx-spring-boot-starter-hibernateファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter</artifactId>
           <version>24.4</version>
      </dependency>
      
      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter-hibernate</artifactId>
           <version>24.4</version>
      </dependency>
    • EclipseLinkがJPAプロバイダの場合は、microtx-spring-boot-starterおよびmicrotx-spring-boot-starter-eclipselinkファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter</artifactId>
           <version>24.4</version>
      </dependency>
      
      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter-eclipselink</artifactId>
           <version>24.4</version>
      </dependency>
    • JDBCアプリケーションでは、microtx-spring-boot-jaxrs-starterファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-jaxrs-starter</artifactId>
           <version>24.4</version>
      </dependency>
    • HibernateがJPAプロバイダの場合は、microtx-spring-boot-jaxrs-starterおよびmicrotx-spring-boot-starter-hibernateファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-jaxrs-starter</artifactId>
           <version>24.4</version>
      </dependency>
      
      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter-hibernate</artifactId>
           <version>24.4</version>
      </dependency>
    • EclipseLinkがJPAプロバイダの場合は、microtx-spring-boot-jaxrs-starterおよびmicrotx-spring-boot-starter-eclipselinkファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-jaxrs-starter</artifactId>
           <version>24.4</version>
      </dependency>
      
      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter-eclipselink</artifactId>
           <version>24.4</version>
      </dependency>
  3. Spring JAX-RSアプリケーションの場合のみ、MicroTxライブラリがJAX-RSコールをインターセプトしてトランザクションを管理できるように、次のフィルタを登録する必要があります。Spring RESTアプリケーションでは、このステップをスキップできます。
    import org.glassfish.jersey.server.ResourceConfig;
    ...
    @Component
    public class Configuration extends ResourceConfig {
        public Configuration() {
    ...
          register(TrmTransactionRequestFilter.class);
          register(TrmTransactionResponseFilter.class);
          register(JaxRsXACallbackResource.class);
    }
  4. @Transactional注釈を使用する場合は、次のステップを実行します。「@Transactionalについて」を参照してください。
    1. org.springframework.transaction.annotation.Transactionalパッケージをインポートします。
      import org.springframework.transaction.annotation.Transactional;
    2. トランザクションを開始するメソッドに@Transactional注釈を付けます。次のコード・サンプルは、@Transactionalの使用方法を示しています。
      import org.springframework.transaction.annotation.Transactional;
      ...
        @RequestMapping(value = "", method = RequestMethod.POST)
        @Transactional(propagation = Propagation.REQUIRED, timeout = 60)
        public ResponseEntity<?> transfer(@RequestBody Transfer transferDetails) {
          // code that is specific to the application's business logic
          // withdraw operation on participant service 1    
          // deposit operation on participant service 2
          }
      

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

    3. 例に示すように、メソッドがResponseEntityオブジェクトを返すことを確認します。これは、トランザクションを処理してResponseBodyFilterクラスをトリガーするために、MicroTxライブラリで必要です。MicroTxでは、com.oracle.microtx.springboot.interceptor.ResponseBodyFilterクラスは@ControllerAdviceで宣言されます。
    4. @Transactionalを使用する場合、begin()commit()およびrollback()を使用してトランザクション境界を指定する必要がないため、ステップ9にスキップします。
  5. com.oracle.microtx.xa.rm.MicroTxUserTransactionServiceパッケージをインポートします。
    import com.oracle.microtx.xa.rm.MicroTxUserTransactionService;
  6. アプリケーション・ロジックがトランザクションを開始する前にMicroTxUserTransactionServiceクラスを自動設定します。
    @Autowired
    MicroTxUserTransactionService microTxUserTransactionService;
  7. オプション。トランザクションをアクティブにしておく期間(ミリ秒)を指定します。トランザクションのコミットまたはロールバックが指定した期間内に行われないと、トランザクションはロールバックされます。これにより、application.yamlファイルのspring.microtx.xa-transaction-timeoutプロパティ値がオーバーライドされます。「トランザクション・タイムアウトの設定」を参照してください。
    microTxUserTransaction.setTransactionTimeout(60000);
  8. 例に示すように、メソッドがResponseEntityオブジェクトを返すことを確認します。
    @RequestMapping(value = "", method = RequestMethod.POST)
    public ResponseEntity<?> transfer(@RequestBody Transfer transferDetails)
    {
     ...
    }
    これは、トランザクションを処理してResponseBodyFilterクラスをトリガーするために、MicroTxライブラリで必要です。MicroTxでは、com.oracle.microtx.springboot.interceptor.ResponseBodyFilterクラスは@ControllerAdviceで宣言されます。
  9. トランザクションを開始するアプリケーション・コード内で、トランザクションの開始、コミット、ロールバックなどのトランザクション境界を設定します。次のコード・サンプルは、新しいXAトランザクションを開始する方法を示しています。
    • アプリケーションがトランザクションを開始するだけでトランザクションに参加しない場合は、次の行をアプリケーション・コードに追加して、XAトランザクションを開始します。

      
      microTxUserTransactionService.begin();
      ... // Implement the business logic to begin a transaction.
    • アプリケーションがトランザクションを開始して参加する場合は、次の行をアプリケーション・コードに追加して、XAトランザクションを開始します。

      
      microTxUserTransactionService.begin(true);
      ... // Implement the business logic to begin a transaction.
      
  10. ビジネス・ロジックに基づいて、トランザクションをコミットまたはロールバックします。
    • トランザクションをコミットするには:

      microTxUserTransactionService.commit();
    • トランザクションをロールバックするには:

      microTxUserTransactionService.rollback();

    次のコード・サンプルは、begin()commit()およびrollback()を使用してトランザクション境界を設定する方法を示しています。

    @RequestMapping(value = "", method = RequestMethod.POST)
    public ResponseEntity<?> transfer(@RequestBody Transfer transferDetails) {
      microTxUserTransactionService.begin();
       // app specific code
      try {
          microTxUserTransactionService.commit();
       } catch (Exception e) {
          microTxUserTransactionService.rollback();
       } 
    }
  11. RESTテンプレートまたはOpenFeignを使用して、トランザクション参加側サービスのエンドポイントをコールし、トランザクションを実行します。トランザクション・イニシエータ・サービスはトランザクションを開始します。トランザクションを完了するために、イニシエータ・サービスは1つ以上の参加側サービスをコールする必要があります。参加側サービスをコールするときに、作成したオブジェクトを使用します。

    次のサンプル・コードに示すように、MicroTxライブラリによって提供されるSpring Boot RestTemplateをオートワイヤします。

    @Autowired
    @Qualifier("MicroTxXaRestTemplate")
    RestTemplate restTemplate;

    次のいずれかの方法で、MicroTxライブラリによって提供されるインターセプタを構成します。これは、送信リクエストがトランザクションの一部である場合、または送信リクエストをインターセプトする場合に必要です。

    • 次の例に示すように、@FeignClient注釈の構成プロパティでインターセプタを構成します。
      @FeignClient(value = "<feign1.name>", url = "<feign1.url>", configuration = MicroTxXaFeignInterceptorConfig.class)
      public interface <interface_name> {
         // ...
      }

      ここで、<feign1.name>および<feign1.url>を環境に固有の値に置き換えます。後でアプリケーション・コードで使用するため、インタフェースの名前を書き留めておきます。

    • 次の例に示すように、プロパティ値を指定してインターセプタを構成します。これらの値は、MicroTxクライアント・ライブラリ・プロパティの値を含む同じファイルに指定します。
      spring.cloud.openfeign.client.config.<feign1_name>.request-interceptors[0]= com.oracle.microtx.springboot.xa.clientinterceptor.MicroTxXaFeignInterceptorConfig

      ここで、<feign1_name>は、@FeignClient注釈のvalueプロパティのデータです。

  12. 変更内容を保存します。
MicroTxライブラリおよびXAを使用するサンプルSpring RESTトランザクション・イニシエータ・アプリケーションのソース・コードは、microtx-samples GitHubリポジトリにあるteller-springフォルダにあります。これは、MicroTxライブラリとアプリケーションの統合時に参照として使用できます。これは、Spring RESTイニシエータ・アプリケーションのビジネス・ロジックでMicroTx Spring RESTライブラリを使用する方法の例です。このサンプル・アプリケーションは振込(Teller)という名前です。これは2つの部門間のトランザクションを開始します。部門Aをコールして一定金額を引き出し、部門Bをコールして預け入れます。
イニシエータ・サービスが、トランザクションを開始するだけでなくトランザクションに参加する場合、トランザクションに参加してリソース・マネージャと通信するアプリケーションのために追加の構成を行う必要があります。「トランザクション参加側としてのSpring Bootアプリケーションの構成」を参照してください。microtx-samples GitHubリポジトリにあるteller-as-participant-springフォルダは、トランザクションに参加もするSpring RESTトランザクション・イニシエータ・アプリケーションのソース・コードを提供します。