6.7 XAでのSpring RESTアプリケーションの開発

Spring RESTアプリケーションでMicroTxライブラリを使用します。

6.7.1 Spring RESTアプリケーションのライブラリ・プロパティの構成

すべてのSpring RESTアプリケーションのMicroTxライブラリ・プロパティの構成情報を指定します。指定する必要があるプロパティ値は、アプリケーションが参加側であるかイニシエータであるかに応じて異なります。

application.yamlファイルでMicroTxライブラリのプロパティ値を指定します。

  • spring.microtx.coordinator-url: MicroTxコーディネータにアクセスするためのURLを入力します。「MicroTxへのアクセス」を参照してください。この値はトランザクション・イニシエータ・アプリケーションの場合に入力する必要があります。トランザクション参加側アプリケーションの場合、この値を指定する必要はありません。

  • spring.microtx.participant-url: 参加側サービスのURLを入力します。MicroTxは、指定されたURLを使用して参加側サービスに接続します。この値を次の形式で指定します。
    https://externalHostnameOfApp:externalPortOfApp/
    説明
    • externalHostnameOfApp: イニシエータ・サービスまたは参加側サービスの外部ホスト名。たとえば、bookTicket-appです。
    • externalPortOfApp: 参加側サービスにリモートでアクセスできるポート番号。たとえば、8081です。
    トランザクション参加側アプリケーションには、この値を指定する必要があります。トランザクション・イニシエータ・アプリケーションでは、この値を指定する必要はありません。

    たとえば、https://bookTicket-app:8081です。

  • spring.microtx.propagation-active: トランザクションを全面的にトレースする場合は、これをtrueに設定します。これにより、すべての受信リクエストおよび送信リクエストのトレース・ヘッダーが伝播されます。

  • spring.microtx.http-client-connection-pool-size: MicroTxライブラリへの接続数をMicroTxに入力します。デフォルト(最小)の接続数は10です。最大値は20です。この値は、サービスが実行する問合せ数に応じて変更できます。この値はイニシエータ・アプリケーションと参加側アプリケーションの両方に指定します。

  • spring.microtx.xa-transaction-timeout: トランザクションをアクティブにしておく最長期間(ミリ秒)を指定します。トランザクションのコミットまたはロールバックが指定した期間内に行われないと、トランザクションはロールバックされます。デフォルト(最小)値は60000です。この値はイニシエータ・アプリケーションと参加側アプリケーションの両方に指定します。
  • spring.microtx.xa-resource-manager-id: XAトランザクションで使用するリソース・マネージャごとに一意の文字列値を指定します。RMIDとして指定する一意の値は、MicroTxがリソース・マネージャを識別するために使用されます。複数の参加側が同じリソース・マネージャを使用する場合、リソース・マネージャを共有する参加側に対して同じリソース・マネージャIDを指定します。この値は、データ・ストアのプロパティとは関係ありません。たとえば、174A5FF2-D8B2-47B0-AF09-DA5AFECA2F71です。
  • spring.microtx.xa-xa-support: XA準拠リソースを使用する場合は、これをtrueに設定します。これをfalseに設定するのは、非XAリソースを使用する単一のトランザクション参加側サービスに対してのみです。デフォルト値はtrueです。xa-xa-supporttrueに設定されると、xa-llr-supportおよびxa-lrc-supportに設定された値は無視されます。
  • spring.microtx.xa-llr-support: ロギング・ラスト・リソース(LLR)の最適化を有効にするには、これをtrueに設定します。この値は、非XAリソースをリソース・マネージャとして使用するトランザクション参加側サービスについてのみ設定します。デフォルト値はfalseです。xa-llr-supporttrueに設定されると、xa-lrc-supportに設定された値は無視されます。

    このプロパティ値をtrueに設定した場合にのみ、xa-llr-delete-commit-record-intervalプロパティの値も指定できます。コミットされたレコードを保持する最長期間(ミリ秒)を指定します。デフォルト値は7,200,000ミリ秒または2時間です。ローカル・コミットを実行する前に、トランザクション・コーディネータはLLRブランチにコミット・レコードを作成します。コミット・レコードは、xa-llr-delete-commit-record-intervalプロパティで指定された期間の後に削除されます。この値は、非XAリソースをリソース・マネージャとして使用するサービスについてのみ指定します。

  • spring.microtx.xa-lrc-support: ラスト・リソース・コミット(LRC)の最適化を有効にするには、これをtrueに設定します。この値は、非XAリソースをリソース・マネージャとして使用するトランザクション参加側サービスについてのみ設定します。デフォルト値はfalseです。
  • spring.microtx.xa-promotable-active: ローカル・トランザクションを有効にするか、コーディネータを使用せずに特定のトランザクションをローカルで管理するには、これをtrueに設定します。この値は、トランザクションにも参加するトランザクション・イニシエータ・サービスに対してのみ指定します。

    デフォルト値はfalseです。xa-promotable-activeの値をfalseに設定すると、すべてのトランザクションがデフォルトでグローバル・トランザクションとして開始され、GTRIDに関連付けられます。ローカル・トランザクションは開始されません。「グローバルおよびローカル・トランザクションについて」を参照してください。

  • spring.microtx.xa-rac-active: これをtrueに設定するのは、Oracle Real Application Clusters (RAC)データベースをリソース・マネージャとして使用するトランザクション参加側サービスに対してのみです。デフォルト値はfalseです。
たとえば、
 spring:
  microtx:
    coordinator-url: http://tmm-app:9000/api/v1
    participant-url: https://bookTicket-app:8081
    propagation-active: true
    http-client-connection-pool-size: 60
    xa-transaction-timeout: 60000
    xa-xa-support: true
    xa-llr-support: false
    xa-lrc-support: false
    xa-llr-delete-commit-record-interval: 720000
    xa-resource-manager-id: 174A5FF2-D8B1-47B0-AF09-DA5AFECA2F61
    xa-promotable-active: false
    xa-rac-active: false

アプリケーションとMicroTxが同じKubernetesクラスタ内にある場合はHTTPプロトコルを使用し、それ以外の場合はHTTPSプロトコルを使用します。

これらの構成値を環境変数として指定することもできます。application.yamlファイルと環境変数の両方に値を指定した場合、環境変数に設定されている値がプロパティ・ファイルの値をオーバーライドすることに注意してください。

次の例は、環境変数を構成するためのサンプル値を示しています。

export SPRING_MICROTX_COORDINATOR_URL = http://tmm-app:9000/api/v1
export SPRING_MICROTX_PARTICIPANT_URL = http://bookTicket-app:8081
export SPRING_MICROTX_PROPAGATION_ACTIVE = true
export SPRING_MICROTX_HTTP_CLIENT_CONNECTION_POOL_SIZE = 15
export SPRING_MICROTX_XA_TRANSACTION_TIMEOUT = 60000
export SPRING_MICROTX_XA_XA_SUPPORT = true
export SPRING_MICROTX_XA_LLR_SUPPORT = false
export SPRING_MICROTX_XA_LLR_DELETE_COMMIT_RECORD_INTERVAL = 720000
export SPRING_MICROTX_XA_LRC_SUPPORT = false
export SPRING_MICROTX_XA_RESOURCE_MANAGER_ID = 174A5FF2-D8B1-47B0-AF09-DA5AFECA2F61
export SPRING_MICROTX_PROMOTABLE_ACTIVE = false
export SPRING_MICROTX_XA_RAC_ACTIVE = false

環境変数名では大/小文字が区別されることに注意してください。

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

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

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

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

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter</artifactId>
           <version>23.4.2</version>
      </dependency>
    • HibernateおよびJDBCアプリケーションでは、microtx-spring-boot-starter-hibernateライブラリ・ファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter-hibernate</artifactId>
           <version>23.4.2</version>
      </dependency>
    • EclipseLinkおよびJDBCアプリケーションでは、microtx-spring-boot-starter-eclipselinkライブラリ・ファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter-eclipselink</artifactId>
           <version>23.4.2</version>
      </dependency>
  3. @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)
        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 RESTアプリケーションでの@Transactionalの使用の詳細は、https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Transactional.htmlを参照してください。

    3. @Transactionalを使用する場合、begin()commit()およびrollback()を使用してトランザクション境界を指定する必要がないため、ステップ8にスキップします。
  4. com.oracle.microtx.xa.rm.MicroTxUserTransactionServiceパッケージをインポートします。
    import com.oracle.microtx.xa.rm.MicroTxUserTransactionService;
  5. アプリケーション・ロジックがトランザクションを開始する前にMicroTxUserTransactionServiceクラスを自動設定します。
    @Autowired
    MicroTxUserTransactionService microTxUserTransactionService;
  6. トランザクションを開始するアプリケーション・コード内で、トランザクションの開始、コミット、ロールバックなどのトランザクション境界を設定します。次のコード・サンプルは、新しいXAトランザクションを開始する方法を示しています。
    • アプリケーションがトランザクションを開始するだけでトランザクションに参加しない場合は、次の行をアプリケーション・コードに追加して、XAトランザクションを開始します。

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

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

      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();
       } 
    }
  8. WebClientまたはRESTテンプレートを使用して、トランザクション参加側サービスのエンドポイントをコールし、トランザクションを実行します。トランザクション・イニシエータ・サービスはトランザクションを開始します。トランザクションを完了するために、イニシエータ・サービスは1つ以上の参加側サービスをコールする必要があります。参加側サービスをコールするときに、作成したオブジェクトを使用します。
    • @Autowired
      @Qualifier("MicroTxXaWebClientBuilder")
      WebClient.Builder webClientBuilder;
    • 次のサンプル・コードに示すように、MicroTxによって提供されたSpring Boot RESTテンプレートを注入します。
      @Autowired
      @Qualifier("MicroTxXaRestTemplate")
      RestTemplate restTemplate;
  9. 変更内容を保存します。
トランザクション・イニシエータ・サービスのサンプルXAアプリケーション・コードは、installation_directory\otmm-RELEASE\samples\xa\java\teller-as-participant-springにあります。これは、Spring RESTイニシエータ・アプリケーションのビジネス・ロジックでMicroTx Spring RESTライブラリを使用する方法の例です。このサンプル・アプリケーションは振込(Teller)という名前です。これは2つの部門間のトランザクションを開始します。部門Aをコールして一定金額を引き出し、部門Bをコールして預け入れます。
イニシエータ・サービスが、トランザクションを開始するだけでなくトランザクションに参加する場合、トランザクションに参加してリソース・マネージャと通信するアプリケーションのために追加の構成を行う必要があります。「トランザクション参加側としてのSpring RESTアプリケーションの構成」を参照してください。

6.7.3 トランザクション参加側としてのSpring RESTアプリケーションの構成

リソース・マネージャがXAに準拠しているかどうかに基づいて、環境変数を設定し、MicroTxライブラリの様々なクラスを実装してSpring REST参加側アプリケーションを構成します。

ノート:

トランザクションに参加するすべてのREST APIで、レスポンス本文がnullではないことを確認してください。

6.7.3.1 XA準拠リソース・マネージャを使用するSpring RESTアプリケーションの構成

XA準拠のリソース・マネージャを使用する場合は、この項に記載されている情報を使用してSpring RESTベースの参加側アプリケーションを構成します。

  1. MicroTxクライアント・ライブラリのプロパティ値を指定します。

    次の例では、プロパティのサンプル値を指定しています。ご自身の環境に基づいて値を指定してください。

     spring:
      microtx:
        participant-url: https://bookTicket-app:8081
        propagation-active: true
        http-client-connection-pool-size: 15
        xa-transaction-timeout: 60000
        xa-resource-manager-id: 174A5FF2-D8B1-47B0-AF09-DA5AFECA2F61
        xa-xa-support: true
    

    xa-xa-supporttrueに設定されていることを確認します。

    各プロパティおよびその他のオプション・プロパティの詳細は、「Spring RESTアプリケーションのライブラリ・プロパティの構成」を参照してください。

  2. 次のMicroTxライブラリ・ファイルの1つのみをSpring Boot 3.xアプリケーションのpom.xmlファイルにmaven依存関係として含めます。次のサンプル・コードは23.4.2リリース用です。使用するリリース・バージョンに基づいて、正しいバージョンを指定してください。Spring Boot 3.xアプリケーションは、Java 17で動作します。
    • JDBCアプリケーションでは、microtx-spring-boot-starterファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter</artifactId>
           <version>23.4.2</version>
      </dependency>
    • HibernateおよびJDBCアプリケーションでは、microtx-spring-boot-starter-hibernateライブラリ・ファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter-hibernate</artifactId>
           <version>23.4.2</version>
      </dependency>
    • EclipseLinkおよびJDBCアプリケーションでは、microtx-spring-boot-starter-eclipselinkライブラリ・ファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter-eclipselink</artifactId>
           <version>23.4.2</version>
      </dependency>
  3. com.oracle.microtx.common.MicroTxConfigパッケージをインポートします。
    import com.oracle.microtx.common.MicroTxConfig;
  4. XADatasourceオブジェクトを初期化します。

    MicroTxクライアント・ライブラリは、XADatasourceオブジェクトにアクセスする必要があります。このオブジェクトを使用してXAConnectionオブジェクトおよびXAResourceオブジェクトを作成し、リソース・マネージャまたはデータベース・サーバーに接続します。次のコードでは、接続オブジェクトを作成する際にアプリケーション・コードの先頭にXADatasourceオブジェクトをどのように定義するかを示しています。

    class oracle.tmm.jta.MicroTxConfig
    static void initXaDataSource(XADataSource xaDs)

    XADataSourceの詳細は、https://docs.oracle.com/javase/8/docs/api/javax/sql/XADataSource.htmlを参照してください。

  5. トランザクション参加側関数またはブロックで、MicroTxクライアント・ライブラリで使用されるXADatasourceオブジェクトを指定します。リソース・マネージャに接続するための資格証明およびその他の詳細を指定します。
    //Example for a participant using an Oracle Database:
    OracleXADataSource dataSource = new oracle.jdbc.xa.client.OracleXADataSource();
    dataSource.setURL(url); //database connection string
    dataSource.setUser(user); //username to access database
    dataSource.setPassword(password); //password to access database
    MicroTxConfig.initXaDataSource((XADataSource)dataSource);

    アプリケーション開発者は、XADataSourceを割り当てる際に、XA準拠JDBCドライバおよび必要なパラメータを設定する必要があります。

    MicroTxクライアント・ライブラリは、XADatasourceオブジェクトを使用してデータベース接続を作成します。

  6. トランザクション参加側の関数すなわちブロックで、XADatasourceオブジェクトを初期化した後に次のコード行を1回だけ追加します。
    oracle.tmm.jta.MicroTxConfig.initXaDataSource((XADataSource)xaDs);

    XADatasourceはJTAで定義されたインタフェースであり、JDBCドライバによって実装が提供されます。

    MicroTxクライアント・ライブラリは、このオブジェクトを使用してデータベースに接続し、XAトランザクションを開始し、準備、コミット、ロールバックなどの様々な操作を実行します。MicroTxライブラリは、依存関係インジェクションを使用してDMLを実行するためのSQL接続オブジェクトもアプリケーション・コードに提供します。

  7. 参加側サービスのコードに次の行を挿入して、アプリケーションがMicroTxクライアント・ライブラリによって渡された接続を使用するようにします。参加側アプリケーションの次のコードは、MicroTxクライアント・ライブラリによって作成されたconnectionオブジェクトを注入します。
    @Autowired
    @Qualifier("microTxSqlConnection")
    @Lazy
    private Connection connection;
  8. 参加側サービスのコードに次の行を挿入して、参加側サービスがDML操作を実行するたびに、注入されたconnectionオブジェクトを使用するようにします。
    Statement stmt1 = connection.createStatement();
    stmt1.execute(query);
    stmt1.close();

    ここで、connectionは、前のステップで注入したConnectionオブジェクトの名前です。

    これらのコード行は、参加側サービスが実行するDML操作ごとに挿入します。DML操作ごとにstmt1stmt2などの新しい文オブジェクトを作成しますが、MicroTxクライアント・ライブラリによって作成された同一のconnectionオブジェクトを使用します。

  9. 変更内容を保存します。
複数のSpring RESTサービスがある場合は、すべてのトランザクション参加側サービスでこれらのステップを完了します。

6.7.3.2 複数のXA準拠リソース・マネージャを使用するSpring RESTアプリケーションの構成

複数のXA準拠のリソース・マネージャを使用する場合は、この項に記載されている情報を使用してSpring REST参加側アプリケーションを構成します。

アプリケーションは、複数のXA準拠リソース・マネージャに接続できます。また、アプリケーションは1つの非XAリソースに接続できます。
  1. 次のMicroTxライブラリ・ファイルの1つのみをSpring Boot 3.xアプリケーションのpom.xmlファイルにmaven依存関係として含めます。次のサンプル・コードは23.4.2リリース用です。使用するリリース・バージョンに基づいて、正しいバージョンを指定してください。Spring Boot 3.xアプリケーションは、Java 17で動作します。
    • JDBCアプリケーションでは、microtx-spring-boot-starterファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter</artifactId>
           <version>23.4.2</version>
      </dependency>
    • HibernateおよびJDBCアプリケーションでは、microtx-spring-boot-starter-hibernateライブラリ・ファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter-hibernate</artifactId>
           <version>23.4.2</version>
      </dependency>
    • EclipseLinkおよびJDBCアプリケーションでは、microtx-spring-boot-starter-eclipselinkライブラリ・ファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter-eclipselink</artifactId>
           <version>23.4.2</version>
      </dependency>
  2. com.oracle.microtx.common.MicroTxConfigパッケージをインポートします。
    import com.oracle.microtx.common.MicroTxConfig;
  3. リソース・マネージャごとにDataSourceInfoオブジェクトを作成します。必ず、アプリケーションのYAMLファイルで指定したデータ・ソース名とリソース・マネージャIDを指定してください。

    サンプル・コマンド

    DataSourceInfo departmentDataSourceInfo = new DataSourceInfo("ORCL1-8976-9776-9873");
    departmentDataSourceInfo.setDataSourceName(departmentDataSource);
    
    DataSourceInfo creditDataSourceInfo = new DataSourceInfo("ORCL2-2134-5668-8672");
    creditDataSourceInfo.setDataSourceName(creditDataSource);

    説明

    • departmentDataSourceおよびcreditDataSourceは、アプリケーションのYAMLファイルで指定したXAデータ・ソースの名前です。
    • ORCL1-8976-9776-9873およびORCL2-2134-5668-8672は、アプリケーションのYAMLファイルでdepartmentDataSourceおよびcreditDataSourceにそれぞれ指定したリソース・マネージャIDです。

    後で、@Inject注釈を使用して、アプリケーションでこれらのデータ・ソースが使用されることを確認します。

  4. 作成したDataSourceInfoオブジェクトごとに、次のMicroTxクライアント・ライブラリ・プロパティの1つのみを入力します。次の例では、creditDataSourceオブジェクトのプロパティ値を指定します。同様に、他のリソース・マネージャのプロパティ値を指定できます。値を指定しない場合、リソースはデフォルトでXA準拠とみなされます。
    • XA準拠リソースの場合は、次を入力します:
      creditDataSource.setXaSupport();
    • Oracle RACデータベースの場合は、次のように入力します:
      creditDataSource.setRAC(true);
    • LLRの最適化を使用する非XAリソースの場合は、次を入力します:
      creditDataSource.setLLRSupport();
    • LRCの最適化を使用する非XAリソースの場合は、次を入力します:
      creditDataSource.setLRCSupport();
  5. XADatasourceオブジェクトを初期化します。アプリケーションで複数のリソース・マネージャを使用している場合は、XA準拠リソース・マネージャごとに次の方法でXADatasourceオブジェクトを初期化します。

    MicroTxクライアント・ライブラリは、XADatasourceオブジェクトにアクセスする必要があります。このオブジェクトを使用してXAConnectionオブジェクトおよびXAResourceオブジェクトを作成し、リソース・マネージャまたはデータベース・サーバーに接続します。次のコードでは、接続オブジェクトを作成する際にアプリケーション・コードの先頭にXADatasourceオブジェクトをどのように定義するかを示しています。

    class oracle.tmm.jta.MicroTxConfig
    static void initXaDataSource(XADataSource dataSource, DataSourceInfo creditDataSource)

    ここで、creditDataSourceは、以前に作成したDataSourceInfoオブジェクトです。

    すべてのリソース・マネージャについてこのステップを繰り返します。

    XADataSourceの詳細は、https://docs.oracle.com/javase/8/docs/api/javax/sql/XADataSource.htmlを参照してください。

  6. トランザクション参加側関数またはブロックで、MicroTxクライアント・ライブラリで使用されるXADatasourceオブジェクトを指定します。リソース・マネージャに接続するための資格証明およびその他の詳細を指定します。
    //Example for a participant using an Oracle Database:
    OracleXADataSource dataSource = new oracle.jdbc.xa.client.OracleXADataSource();
    dataSource.setURL(url); //database connection string
    dataSource.setUser(user); //username to access database
    dataSource.setPassword(password); //password to access database

    アプリケーション開発者は、XADataSourceを割り当てる際に、XA準拠JDBCドライバおよび必要なパラメータを設定する必要があります。

    MicroTxクライアント・ライブラリは、XADatasourceオブジェクトを使用してデータベース接続を作成します。

    すべてのリソース・マネージャについてこのステップを繰り返します。

  7. トランザクション参加側の関数すなわちブロックで、XADatasourceオブジェクトを初期化した後に次のコード行を1回だけ追加します。
    oracle.tmm.jta.MicroTxConfig.initXaDataSource(dataSource, creditDataSource)

    ここで、 creditDataSourceは、以前に作成したDataSourceInfoオブジェクトです。

    MicroTxクライアント・ライブラリは、このオブジェクトを使用してデータベースに接続し、XAトランザクションを開始し、準備、コミット、ロールバックなどの様々な操作を実行します。MicroTxライブラリは、依存関係インジェクションを使用してDMLを実行するためのSQL接続オブジェクトもアプリケーション・コードに提供します。

    すべてのリソース・マネージャについてこのステップを繰り返します。

  8. 参加側サービスのコードに次の行を挿入して、アプリケーションがMicroTxクライアント・ライブラリによって渡された接続を使用するようにします。参加側アプリケーションの次のコードは、MicroTxクライアント・ライブラリによって作成されたconnectionオブジェクトを注入します。

    アプリケーションで複数のリソース・マネージャを使用している場合は、XA準拠リソース・マネージャごとに次の方法でconnectionオブジェクトを注入します。

    次の例では、XA準拠リソース・マネージャごとに1つずつ、2つの接続を追加する方法について説明します。接続を注入する場合は、microTxSqlConnectionをコールし、その後にデータ・ソースの名前を指定します。

    //Initialize the application context
    private ApplicationContext applicationContext;
    //Connection for XA-compliant resource manager 1
    private Connection connection;
    //Connection for XA-compliant resource manager 2
    private Connection creditConnection;
    
    @Autowired
        public AccountService(ApplicationContext applicationContext) {
            this.applicationContext = applicationContext;
            try {
                // Inject the connections for XA-compliant resource manager 1.
                // Specify the name of the data source associated with XA-compliant resource manager 1.            
                connection =  (Connection) applicationContext.getBean("microTxSqlConnection", "departmentDataSource");
                // Inject the connections for XA-compliant resource manager 2.
                // Specify the name of the data source associated with XA-compliant resource manager 2. 
                creditConnection =  (Connection) applicationContext.getBean("microTxSqlConnection","creditDataSource");
            } catch (ClassCastException ex) {
                LOG.info(ex.getMessage());
            }
       }

    ここで、creditDataSourceは、oracle.tmm.jta.common.DataSourceInfoパッケージのDataSourceInfoクラスのdataSourceName文字列に指定した値です。

    すべてのリソース・マネージャについてこのステップを繰り返します。

  9. 参加側サービスのコードに次の行を挿入して、参加側サービスがDML操作を実行するたびに、注入されたconnectionオブジェクトを使用するようにします。
    Statement stmt1 = creditConnection.createStatement();
    stmt1.execute(query);
    stmt1.close();

    ここで、creditConnectionは、前のステップで注入したConnectionオブジェクトの名前です。

    これらのコード行は、参加側サービスが実行するDML操作ごとに挿入します。DML操作ごとにstmt1stmt2などの新しい文オブジェクトを作成しますが、MicroTxクライアント・ライブラリによって作成された同一のcreditConnectionオブジェクトを使用します。

    すべてのリソース・マネージャについてこのステップを繰り返します。

  10. 変更内容を保存します。
複数のSpring RESTトランザクション参加側サービスがある場合は、すべての参加側サービスでこれらのステップを完了します。

6.7.3.3 非XA JDBCリソースを使用するSpring RESTアプリケーションの構成

XAをサポートしないJDBCリソースを使用する場合は、この項に記載されている情報を使用してSpring REST参加側アプリケーションを構成します。

アプリケーションは、複数のXA準拠リソース・マネージャに接続できます。また、アプリケーションは1つの非XAリソースに接続できます。
  1. 1つのリソース・マネージャを使用する場合は、すべてのMicroTxクライアント・ライブラリ・プロパティの値を1つのファイル(application.yamlファイルなど)に指定します。アプリケーションで複数のリソース・マネージャを使用している場合は、このステップをスキップします。

    xa-xa-supportfalseに設定され、xa-llr-supportまたはxa-lrc-supporttrueに設定されていることを確認します。

    • ロギング・ラスト・リソース(LLR)の最適化を有効にするには、次のプロパティの値を設定します。
      spring:
        microtx:
          xa-xa-support = false
          xa-llr-support = true
          xa-lrc-support = false
          http-client-connection-pool-size = 15
          participant-url = https://bookHotel-app:8081
          propagation-active = true
          xa-transaction-timeout = 60000
    • ラスト・リソース・コミット(LRC)の最適化を有効にするには、次のプロパティの値を設定します。
      spring:
        microtx:
          xa-xa-support = false
          xa-llr-support = false
          xa-lrc-support = true
          http-client-connection-pool-size = 15
          participant-url = https://bookHotel-app:8081
          propagation-active = true
          xa-transaction-timeout = 60000

    各プロパティおよびその他のオプション・プロパティの詳細は、「Spring RESTアプリケーションのライブラリ・プロパティの構成」を参照してください。

  2. アプリケーションで複数のリソース・マネージャを使用している場合は、次のステップを実行して、MicroTxクライアント・ライブラリのプロパティ値を構成します。1つのリソース・マネージャを使用している場合は、このステップをスキップします。
    1. リソース・マネージャごとにDataSourceInfoオブジェクトを作成します。必ず、アプリケーションのYAMLファイルで指定したデータ・ソース名とリソース・マネージャIDを指定してください。

      サンプル・コマンド

      DataSourceInfo departmentDataSourceInfo = new DataSourceInfo("ORCL1-8976-9776-9873");
      departmentDataSourceInfo.setDataSourceName(departmentDataSource);
      
      DataSourceInfo creditDataSourceInfo = new DataSourceInfo("ORCL2-2134-5668-8672");
      creditDataSourceInfo.setDataSourceName(creditDataSource);

      説明

      • departmentDataSourceおよびcreditDataSourceは、アプリケーションのYAMLファイルで指定したXAデータ・ソースの名前です。
      • ORCL1-8976-9776-9873およびORCL2-2134-5668-8672は、アプリケーションのYAMLファイルでdepartmentDataSourceおよびcreditDataSourceにそれぞれ指定したリソース・マネージャIDです。

      後で、@Inject注釈を使用して、アプリケーションでこれらのデータ・ソースが使用されることを確認します。

    2. 作成したDataSourceInfoオブジェクトごとに、次のMicroTxクライアント・ライブラリ・プロパティの1つのみを入力します。次の例では、creditDataSourceオブジェクトのプロパティ値を指定します。同様に、他のリソース・マネージャのプロパティ値を指定できます。値を指定しない場合、リソースはデフォルトでXA準拠とみなされます。
      • XA準拠リソースの場合は、creditDataSource.setXaSupport();と入力します。
      • LLRの最適化を使用する非XAリソースの場合は、 creditDataSource.setLLRSupport();と入力します。
      • LRCの最適化を使用する非XAリソースの場合は、 creditDataSource.setLRCSupport();と入力します。
  3. 次のMicroTxライブラリ・ファイルの1つのみをSpring Boot 3.xアプリケーションのpom.xmlファイルにmaven依存関係として含めます。次のサンプル・コードは23.4.2リリース用です。使用するリリース・バージョンに基づいて、正しいバージョンを指定してください。Spring Boot 3.xアプリケーションは、Java 17で動作します。
    • JDBCアプリケーションでは、microtx-spring-boot-starterファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter</artifactId>
           <version>23.4.2</version>
      </dependency>
    • HibernateおよびJDBCアプリケーションでは、microtx-spring-boot-starter-hibernateライブラリ・ファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter-hibernate</artifactId>
           <version>23.4.2</version>
      </dependency>
    • EclipseLinkおよびJDBCアプリケーションでは、microtx-spring-boot-starter-eclipselinkライブラリ・ファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter-eclipselink</artifactId>
           <version>23.4.2</version>
      </dependency>
  4. セッション・アフィニティを有効にします。「セッション・アフィニティの有効化」を参照してください。
  5. com.oracle.microtx.common.MicroTxNonXAConfigパッケージをインポートします。
    import com.oracle.microtx.common.MicroTxNonXAConfig;
  6. Datasourceオブジェクトを初期化します。

    MicroTxライブラリは、データ・ソース・オブジェクトにアクセスする必要があります。データ・ソース・オブジェクトを使用してjava.sql.Connectionオブジェクトを作成し、リソース・マネージャに接続します。次のコードは、データ・ソース・オブジェクトを定義する方法を示しています。

    このコードはアプリケーションの最初に指定する必要があります。したがって、initNonXaDataSourceメソッドは、サーバーの起動直後に、他のすべてのリクエストが処理される前にコールされます。

    • アプリケーションで1つのリソース・マネージャを使用している場合は、次のようにデータ・ソースを初期化します。

      class oracle.tmm.jta.MicroTxNonXAConfig
      static void initNonXaDataSource(DataSource NonXaDs)
    • アプリケーションで複数のリソース・マネージャを使用している場合は、非XA JDBCリソースに対して次の方法でデータ・ソース・オブジェクトを初期化します。参加側サービスは複数のXA準拠リソース・マネージャに接続できますが、1つのトランザクションでサポートされる非XAリソースは1つのみです。

      class oracle.tmm.jta.MicroTxNonXAConfig
      static void initNonXaDataSource(DataSource departmentDataSource, DataSourceInfo departmentDataSourceInfo)

      ここで、dataSourceInfoは、ステップ2で作成したオブジェクトです。

  7. トランザクション参加側関数またはブロックで、MicroTxライブラリで使用されるDataSourceオブジェクトを指定します。リソース・マネージャに接続するための資格証明およびデータベース・ドライバの詳細を指定します。次の例は、MySQLデータベースをLLRとして使用する場合に指定する必要がある詳細を示しています。同様に、他のデータベースの資格証明およびデータベース・ドライバ情報を指定できます。
    //Example for a participant using a MySQL database as resource manager
    this.dataSource = PoolDataSourceFactory.getPoolDataSource();
    this.dataSource.setURL(url); //Database connection string
    this.dataSource.setUser(user); //User name to access the database
    this.dataSource.setPassword(password); //Password to access the database
    //Database driver information for the MySQL database.
    //Provide the JDBC driver information that is specific to your database.
    this.dataSource.setConnectionFactoryClassName("com.mysql.cj.jdbc.MysqlDataSource");
    this.dataSource.setMaxPoolSize(15);

    アプリケーション開発者は、DataSourceを割り当てる際に、データベース固有のJDBCドライバおよび必要なパラメータを設定する必要があります。

    MicroTxライブラリは、DataSourceオブジェクトを使用してデータベース接続を作成します。

  8. トランザクション参加側の関数すなわちブロックで、Datasourceオブジェクトを初期化した後に次のコード行を1回だけ追加します。MicroTxライブラリは、このオブジェクトを使用してデータベース・トランザクションを開始します。MicroTxライブラリは、依存関係インジェクションを使用してDMLを実行するためのSQL接続オブジェクトもアプリケーション・コードに提供します。
    oracle.tmm.jta.MicroTxNonXAConfig.initNonXaDataSource((DataSource) NonXaDs);

    ここで、DatasourceはJTAで定義されたインタフェースであり、JDBCドライバによって実装が提供されます。

  9. 参加側サービスのコードに次の行を挿入して、アプリケーションがMicroTxライブラリによって渡された接続を使用するようにします。参加側アプリケーションの次のコードは、MicroTxライブラリによって作成されたconnectionオブジェクトを注入します。
    @Autowired
    @Qualifier("microTxNonXASqlConnection")
    @Lazy
    private Connection connection;
  10. 参加側サービスにコードを挿入して、参加側サービスがDML操作を実行するたびに、注入されたconnectionオブジェクトを使用するようにします。ビジネス・シナリオに基づいて、注入されたconnectionオブジェクトを使用するコードを作成できます。次に、例のコード・スニペットを示します。
    Statement stmt1 = connection.createStatement();
    stmt1.execute(query);
    stmt1.close();

    これらのコード行は、参加側サービスが実行するDML操作ごとに挿入します。DML操作ごとにstmt1stmt2などの新しい文オブジェクトを作成しますが、MicroTxライブラリによって作成された同一のconnectionオブジェクトを使用します。

  11. 変更内容を保存します。

6.7.3.4 非XAかつ非JDBCのリソースを使用するSpring RESTアプリケーションの構成

XAもJDBCもサポートしないリソースを使用する場合は、この項に記載されている情報を使用してSpring REST参加側アプリケーションを構成します。

アプリケーションは、複数のXA準拠リソース・マネージャに接続できます。ただし、トランザクションに参加できるのは1つの非XAリソースのみです。
  1. 開始する前に、MicroTxライブラリのプロパティ値を構成していることを確認してください。

    xa-xa-supportfalseに設定され、xa-llr-supportまたはxa-lrc-supporttrueに設定されていることを確認します。

    • ロギング・ラスト・リソース(LLR)の最適化を有効にするには、次のプロパティの値を設定します。
      spring:
        microtx:
          xa-xa-support = false
          xa-llr-support = true
          xa-lrc-support = false
    • ラスト・リソース・コミット(LRC)の最適化を有効にするには、次のプロパティの値を設定します。
      spring:
        microtx:
          xa-xa-support = false
          xa-llr-support = false
          xa-lrc-support = true

    各プロパティおよびその他のオプション・プロパティの詳細は、「Spring RESTアプリケーションのライブラリ・プロパティの構成」を参照してください。

  2. 次のMicroTxライブラリ・ファイルの1つのみをSpring Boot 3.xアプリケーションのpom.xmlファイルにmaven依存関係として含めます。次のサンプル・コードは23.4.2リリース用です。使用するリリース・バージョンに基づいて、正しいバージョンを指定してください。Spring Boot 3.xアプリケーションは、Java 17で動作します。
    • JDBCアプリケーションでは、microtx-spring-boot-starterファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter</artifactId>
           <version>23.4.2</version>
      </dependency>
    • HibernateおよびJDBCアプリケーションでは、microtx-spring-boot-starter-hibernateライブラリ・ファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter-hibernate</artifactId>
           <version>23.4.2</version>
      </dependency>
    • EclipseLinkおよびJDBCアプリケーションでは、microtx-spring-boot-starter-eclipselinkライブラリ・ファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter-eclipselink</artifactId>
           <version>23.4.2</version>
      </dependency>
  3. セッション・アフィニティを有効にします。「セッション・アフィニティの有効化」を参照してください。
  4. NonXAResourceインタフェースを実装します。
    public class MongoDbNonXAResource implements NonXAResource {
    // Provide application-specific code for all the methods in the NonXAResource interface.
    }

    NonXAResourceインタフェースの詳細は、Transaction Manager for Microservices Java APIリファレンスを参照してください。

    LRCの最適化を有効にした場合、recover()メソッドをNonXAResourceインタフェースに実装する必要はありません。LRCでは、commit()メソッドがcommitRecordNULLを返すためです。

  5. NonXAResourceインタフェースを実装した後、MicroTxライブラリ・ファイルをインポートし、非XAリソースを生成します。作成した非XAリソースに@NonXa注釈を付けます。MicroTxライブラリは、注釈を付けたオブジェクトを消費します。

    次の例は、MongoDBリソースの実装例を示しています。業務要件に基づいてアプリケーションのコードを作成します。この例で、NonXaResourceFactoryクラスがNonXAResourceを提供します。非XAリソースを生成し、MicroTxライブラリが非XAリソースを消費します。

    package com.oracle.mtm.sample.nonxa;
    
    import oracle.tmm.jta.nonxa.NonXAResource;
    import oracle.tmm.jta.nonxa.NonXa;
    
    import javax.enterprise.inject.Produces;
    import javax.inject.Inject;
    import javax.ws.rs.ext.Provider;
    import java.util.function.Supplier;
    
    @Provider
    public class NonXaResourceFactory implements Supplier<NonXAResource> {
    
    @Autowired(required = false)
    @Qualifier("NonXA")
    private NonXAResource trmNonXAInstance;
    
        @Produces    
        @NonXa
        public NonXAResource getNonXAResource() {
            return nonXAResource;
        }
    
      @Override
        public NonXAResource get() {
            return getNonXAResource();
        }
    }
  6. 変更内容を保存します。

6.7.3.5 XA準拠リソース・マネージャを使用するJPAベースのSpring RESTアプリケーションの構成

XA準拠のリソース・マネージャを使用する場合は、この項に記載されている情報を使用して、XAトランザクションに参加するHelidonまたはSpring RESTアプリケーションのJPAプロバイダとしてHibernateまたはEclipseLinkを構成します。

アプリケーションは、複数のXA準拠リソース・マネージャに接続できます。アプリケーションで複数のXA準拠リソース・マネージャを使用している場合は、リソース・マネージャごとに次のステップを実行します。
  1. MicroTxクライアント・ライブラリのプロパティ値を指定します。

    次の例では、プロパティのサンプル値を指定しています。ご自身の環境に基づいて値を指定してください。

    spring:
      microtx:
        participant-url: https://bookTicket-app:8081
        propagation-active: true
        http-client-connection-pool-size: 15
        xa-transaction-timeout: 60000
        xa-resource-manager-id: 174A5FF2-D8B1-47B0-AF09-DA5AFECA2F61
        xa-xa-support: true
    

    xa-xa-supporttrueに設定されていることを確認します。

    各プロパティおよびその他のオプション・プロパティの詳細は、「Spring RESTアプリケーションのライブラリ・プロパティの構成」を参照してください。

  2. 次のMicroTxライブラリ・ファイルの1つのみをSpring Boot 3.xアプリケーションのpom.xmlファイルにmaven依存関係として含めます。次のサンプル・コードは23.4.2リリース用です。使用するリリース・バージョンに基づいて、正しいバージョンを指定してください。Spring Boot 3.xアプリケーションは、Java 17で動作します。
    • JDBCアプリケーションでは、microtx-spring-boot-starterファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter</artifactId>
           <version>23.4.2</version>
      </dependency>
    • HibernateおよびJDBCアプリケーションでは、microtx-spring-boot-starter-hibernateライブラリ・ファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter-hibernate</artifactId>
           <version>23.4.2</version>
      </dependency>
    • EclipseLinkおよびJDBCアプリケーションでは、microtx-spring-boot-starter-eclipselinkライブラリ・ファイルを使用します。

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter-eclipselink</artifactId>
           <version>23.4.2</version>
      </dependency>
  3. アプリケーション・コードを含むフォルダに.javaファイルを作成して、XADataSourceConfigオブジェクトを初期化します。XADataSourceConfigクラスには、カスタム・データ・ソース・オブジェクトおよびエンティティ・マネージャ・ファクトリ・オブジェクトを作成するメソッドが含まれています。

    カスタム・データ・ソース・オブジェクトには、リソース・マネージャに接続するための詳細が含まれています。アプリケーション開発者は、カスタム・データ・ソース・オブジェクトを作成する際に、XA準拠JDBCドライバおよび必要なパラメータを設定する必要があります。

    • Spring RESTを使用するHibernateアプリケーションの次のコード例は、XADataSourceConfigクラス内のライブラリを初期化し、departmentDataSourceというカスタム・データ・ソースを作成し、emfというエンティティ・マネージャ・ファクトリ・オブジェクトを作成する方法を示しています。ご自身のアプリケーション用に同様のコードを作成できます。

      hibernate.connection.provider_classのプロパティ値としてcom.oracle.microtx.jpa.HibernateXADataSourceConnectionProviderが指定されていることを確認してください。

      package com.oracle.mtm.sample;
      
      import com.oracle.microtx.common.MicroTxConfig;
      import oracle.ucp.jdbc.PoolDataSourceFactory;
      import oracle.ucp.jdbc.PoolXADataSource;
      import org.hibernate.jpa.HibernatePersistenceProvider;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.ComponentScan;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.context.annotation.Primary;
      import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
      import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
      
      import javax.persistence.EntityManagerFactory;
      import javax.sql.DataSource;
      import javax.sql.XADataSource;
      import java.sql.SQLException;
      import java.util.Properties;
      
      @Configuration
      @ComponentScan("com.oracle")
      public class XADataSourceConfig {
          @Value("${departmentDataSource.url}")
          private String url;
          @Value("${departmentDataSource.user}")
          private String username;
          @Value("${departmentDataSource.password}")
          private String password;
          @Value("${departmentDataSource.oracleucp.min-pool-size}")
          private String minPoolSize;
          @Value("${departmentDataSource.oracleucp.initial-pool-size:10}")
          private String initialPoolSize;
      
          @Value("${departmentDataSource.oracleucp.max-pool-size}")
          private String maxPoolSize;
      
          @Value("${departmentDataSource.oracleucp.data-source-name}")
          private String dataSourceName;
      
          @Value("${departmentDataSource.oracleucp.connection-pool-name}")
          private String connectionPoolName;
      
          @Value("${departmentDataSource.oracleucp.connection-factory-class-name:oracle.jdbc.xa.client.OracleXADataSource}")
          private String connectionFactoryClassName;
      
          @Value("${spring.microtx.xa-resource-manager-id}")
          private String resourceManagerId;
      
          @Bean(name = "ucpXADataSource")
          @Primary
          public DataSource getDataSource() {
              DataSource pds = null;
              try {
                  pds = PoolDataSourceFactory.getPoolXADataSource();
      
                  ((PoolXADataSource) pds).setConnectionFactoryClassName(connectionFactoryClassName);
                  ((PoolXADataSource) pds).setURL(url);
                  ((PoolXADataSource) pds).setUser(username);
                  ((PoolXADataSource) pds).setPassword(password);
                  ((PoolXADataSource) pds).setMinPoolSize(Integer.valueOf(minPoolSize));
                  ((PoolXADataSource) pds).setInitialPoolSize(Integer.valueOf(initialPoolSize));
                  ((PoolXADataSource) pds).setMaxPoolSize(Integer.valueOf(maxPoolSize));
      
                  ((PoolXADataSource) pds).setDataSourceName(dataSourceName);
                  ((PoolXADataSource) pds).setConnectionPoolName(connectionPoolName);
      
                  System.out.println("XADataSourceConfig: XADataSource created");
              } catch (SQLException ex) {
                  System.err.println("Error connecting to the database: " + ex.getMessage());
              }
              return pds;
          }
      
      
          @Bean(name = "entityManagerFactory")
          public EntityManagerFactory createEntityManagerFactory() throws SQLException {
              LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
      
              entityManagerFactoryBean.setDataSource(getDataSource());
              entityManagerFactoryBean.setPackagesToScan(new String[] { "com.oracle.mtm.sample.entity" });
              entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
      
              entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
              entityManagerFactoryBean.setPersistenceUnitName("mydeptxads");
              Properties properties = new Properties();
              properties.setProperty( "javax.persistence.transactionType", "RESOURCE_LOCAL"); // change this to resource_local
              properties.put("hibernate.show_sql", "true");
              properties.put("hibernate.dialect", "org.hibernate.dialect.Oracle12cDialect");
              properties.put("hibernate.format_sql", "true");
              properties.put("hbm2ddl.auto", "validate");
              properties.put("hibernate.connection.provider_class", "com.oracle.microtx.jpa.HibernateXADataSourceConnectionProvider");
              entityManagerFactoryBean.setJpaProperties(properties);
              entityManagerFactoryBean.afterPropertiesSet();
              EntityManagerFactory emf = (EntityManagerFactory) entityManagerFactoryBean.getObject();
              System.out.println("entityManagerFactory = " + emf);
              MicroTxConfig.initEntityManagerFactory(emf, resourceManagerId); // Initialize TMM Library
              return emf;
          }
      }
    • Spring RESTを使用するEcpliseLinkアプリケーションの次のコード例は、PoolXADataSourceクラス内のライブラリを初期化し、departmentDataSourceというカスタム・データ・ソースを作成し、emfというエンティティ・マネージャ・ファクトリ・オブジェクトを作成する方法を示しています。ご自身のアプリケーション用に同様のコードを作成できます。

      次のサンプル・コードに記載されているとおりにPersistenceUnitProperties.JDBC_CONNECTORおよびPersistenceUnitProperties.SESSION_EVENT_LISTENER_CLASSプロパティの値が指定されていることを確認してください。

      package com.oracle.mtm.sample;
      
      import com.oracle.microtx.common.MicroTxConfig;
      import oracle.ucp.jdbc.PoolDataSourceFactory;
      import oracle.ucp.jdbc.PoolXADataSource;
      import org.eclipse.persistence.config.PersistenceUnitProperties;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.ComponentScan;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.context.annotation.Primary;
      import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
      import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
      import org.eclipse.persistence.jpa.PersistenceProvider;
      
      import javax.persistence.EntityManagerFactory;
      import javax.sql.DataSource;
      import javax.sql.XADataSource;
      import java.sql.SQLException;
      import java.util.Properties;
      
      @Configuration
      @ComponentScan("com.oracle.microtx")
      public class XADataSourceConfig {
          @Value("${departmentDataSource.url}")
          private String url;
          @Value("${departmentDataSource.user}")
          private String username;
          @Value("${departmentDataSource.password}")
          private String password;
      
          @Value("${departmentDataSource.oracleucp.min-pool-size}")
          private String minPoolSize;
          @Value("${departmentDataSource.oracleucp.initial-pool-size:10}")
          private String initialPoolSize;
      
          @Value("${departmentDataSource.oracleucp.max-pool-size}")
          private String maxPoolSize;
      
          @Value("${departmentDataSource.oracleucp.data-source-name}")
          private String dataSourceName;
      
          @Value("${departmentDataSource.oracleucp.connection-pool-name}")
          private String connectionPoolName;
      
          @Value("${departmentDataSource.oracleucp.connection-factory-class-name:oracle.jdbc.xa.client.OracleXADataSource}")
          private String connectionFactoryClassName;
      
          @Value("${spring.microtx.xa-resource-manager-id}")
          private String resourceManagerId;
      
         @Bean(name = "ucpXADataSource")
          @Primary
          public DataSource getDataSource() {
              DataSource pds = null;
              try {
                  pds = PoolDataSourceFactory.getPoolXADataSource();
      
                  ((PoolXADataSource) pds).setConnectionFactoryClassName(connectionFactoryClassName);
                  ((PoolXADataSource) pds).setURL(url);
                  ((PoolXADataSource) pds).setUser(username);
                  ((PoolXADataSource) pds).setPassword(password);
                  ((PoolXADataSource) pds).setMinPoolSize(Integer.valueOf(minPoolSize));
                  ((PoolXADataSource) pds).setInitialPoolSize(Integer.valueOf(initialPoolSize));
                  ((PoolXADataSource) pds).setMaxPoolSize(Integer.valueOf(maxPoolSize));
      
                  ((PoolXADataSource) pds).setDataSourceName(dataSourceName);
                  ((PoolXADataSource) pds).setConnectionPoolName(connectionPoolName);
      
      
                  System.out.println("XADataSourceConfig: XADataSource created");
              } catch (SQLException ex) {
                  System.err.println("Error connecting to the database: " + ex.getMessage());
              }
              return pds;
          }
      
          @Bean(name = "entityManagerFactory")
          public EntityManagerFactory createEntityManagerFactory() throws SQLException {
              LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
      
              entityManagerFactoryBean.setDataSource(getDataSource());
              entityManagerFactoryBean.setPackagesToScan(new String[] { "com.oracle.mtm.sample.entity" });
              entityManagerFactoryBean.setJpaVendorAdapter(new EclipseLinkJpaVendorAdapter());
              entityManagerFactoryBean.setPersistenceProviderClass(PersistenceProvider.class);
              entityManagerFactoryBean.setPersistenceUnitName("mydeptxads");
      
              Properties properties = new Properties();
              properties.setProperty( "javax.persistence.transactionType", "RESOURCE_LOCAL"); // change this to resource_local
              properties.setProperty("javax.persistence.jdbc.driver", "oracle.jdbc.OracleDriver");
              properties.setProperty("javax.persistence.jdbc.url", url);
              properties.setProperty("javax.persistence.jdbc.user", username);
              properties.setProperty("javax.persistence.jdbc.password", password);
      
              properties.setProperty(PersistenceUnitProperties.CACHE_SHARED_DEFAULT, "false");
              properties.setProperty(PersistenceUnitProperties.TARGET_DATABASE, "Oracle");
              properties.setProperty(PersistenceUnitProperties.WEAVING, "false");
              properties.setProperty(PersistenceUnitProperties.JDBC_CONNECTOR, "com.oracle.microtx.eclipselink.EclipseLinkXADataSourceConnector");
              properties.setProperty(PersistenceUnitProperties.SESSION_EVENT_LISTENER_CLASS, "com.oracle.microtx.eclipselink.EclipseLinkXASessionEventAdaptor");
      
              entityManagerFactoryBean.setJpaProperties(properties);
              entityManagerFactoryBean.afterPropertiesSet();
              EntityManagerFactory emf = (EntityManagerFactory) entityManagerFactoryBean.getObject();
              System.out.println("entityManagerFactory = " + emf);
              MicroTxConfig.initEntityManagerFactory(emf, resourceManagerId); // Initialize TMM Library
              return emf;
          }
      }
  4. エンティティ・マネージャ・ファクトリ・オブジェクトを初期化するには、アプリケーションが1つのリソース・マネージャまたは複数のリソース・マネージャに接続するかに応じて、必要なパラメータをMicroTxConfig.initEntityManagerFactory()に渡します。
    • アプリケーションが1つのリソース・マネージャに接続する場合は、エンティティ・マネージャ・ファクトリ・オブジェクトを作成し、それをMicroTxライブラリに渡します。次のサンプル・コードで、emfはエンティティ・マネージャ・ファクトリ・オブジェクトの名前です。

      MicroTxConfig.initEntityManagerFactory(emf);
    • アプリケーションが複数のリソース・マネージャに接続する場合は、MicroTxConfig.initEntityManagerFactory()をコールするときに次のパラメータを渡す必要があります。

      MicroTxConfig.initEntityManagerFactory(emf, departmentDataSource, ORCL1-8976-9776-9873);

      説明

      • emfは、作成したエンティティ・マネージャ・ファクトリ・オブジェクトです。これをMicroTxライブラリに渡します。
      • departmentDataSourceは、前述のサンプル・コードでMicroTxConfig.initEntityManagerFactory()をコールする前に作成したデータ・ソースの名前です。
      • ORCL1-8976-9776-9873は、リソース・マネージャID (RMID)です。
  5. 参加側サービスのコードに次の行を挿入して、アプリケーションがMicroTxクライアント・ライブラリによって渡された接続を使用するようにします。参加側アプリケーションの次のコードは、MicroTxクライアント・ライブラリによって作成されたconnectionオブジェクトを注入します。
    • 1つのアプリケーションで1つのリソース・マネージャを使用する場合は、次のコード・サンプルに示すようにEntityManagerオブジェクトを注入します。ここで、microTxEntityManagerはエンティティ・マネージャ・ファクトリ・オブジェクトの名前です。

      @Autowired
      @Qualifier("microTxEntityManager")
      @Lazy
      private EntityManager entityManager;
    • アプリケーションで複数のリソース・マネージャを使用する場合は、次のコード・サンプルに示すようにリソース・マネージャごとにEntityManagerオブジェクトを注入します。

      //Initialize the application context
      private ApplicationContext applicationContext;
      //Entity Manager object for XA-compliant resource manager 1
      private EntityManager entityManager;
      //Entity Manager object for XA-compliant resource manager 2
      private EntityManager creditEntityManager;
      @Autowired
          public AccountService(ApplicationContext applicationContext) {
              this.applicationContext = applicationContext;
              try {
                  entityManager =  (EntityManager) applicationContext.getBean("microTxEntityManager", "departmentDataSource");
                  creditEntityManager =  (EntityManager) applicationContext.getBean("microTxEntityManager", "creditDataSource");
              } catch (ClassCastException ex) {
                  LOG.info(ex.getMessage());
              }
          }

      ここで、microTxEntityManagerはエンティティ・マネージャ・ファクトリ・オブジェクト、departmentDataSourceおよびcreditDataSourceは前のステップで作成したデータ・ソース・オブジェクトです。前のコード・サンプルは、departmentDataSourceの詳細を示しています。同様の方法で、creditDataSourceなどの他のリソース・マネージャの情報を指定します。

      すべてのリソース・マネージャについてこのステップを繰り返します。

  6. アプリケーション・コードで、MicroTxライブラリに渡したエンティティ・マネージャ・オブジェクトを注入します。ビジネス・ロジックに基づいてアプリケーション・コード内でエンティティ・マネージャ・オブジェクトを使用し、このオブジェクトを使用してデータベースに接続します。
  7. 変更内容を保存します。
複数のトランザクション参加側サービスがある場合は、すべての参加側サービスでこれらのステップを完了します。