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

  1. MicroTxライブラリのプロパティ値を指定します。「ORDSアプリケーションのPL/SQLライブラリ・プロパティの構成」を参照してください。
  2. REST APIごとに、テンプレートおよびハンドラを定義します。
    1. RESTサービス・モジュールの名前およびベース・パスを入力します。次のコード例は、値としてtellerおよびtransfersを指定しています。これらの値は、ご使用の環境に固有の情報で置き換えてください。
      DECLARE
          //Provide a name for the REST service module
          restModuleName VARCHAR2(256):= 'teller'; 
          //Provide a base path for the REST service
          restModuleBasePath VARCHAR2(256):= 'transfers';
    2. モジュールを定義し、そのモジュールのテンプレートを定義します。
      
      BEGIN
          ORDS.define_module(
                  p_module_name    => restModuleName,
                  p_base_path      => restModuleBasePath,
                  p_items_per_page => 0);
       
          ORDS.define_template(
                  p_module_name    => restModuleName,
                  p_pattern        => 'transfer');
    3. モジュールのソース・コードを指定します。次のコード・スニペットは、MicroTx PL/SQLライブラリ関数、tmm_begin_tx()tmm_rollback_tx()およびtmm_commit_tx()を使用してトランザクション境界を定義する方法を示しています。トランザクションを開始すると、MicroTxTransactionオブジェクトが返されます。この返されたオブジェクトを使用して、グローバル・トランザクションをコミットまたはロールバックします。PL/SQL関数のリファレンス情報は、「MicroTx PL/SQLライブラリ関数」を参照してください。
      
      ORDS.define_handler(
          p_module_name    => restModuleName,
          p_pattern        => 'transfer',
          p_method         => 'POST',
          p_source_type    => ORDS.source_type_plsql,
          p_source         => '
              DECLARE
              payload      JSON_OBJECT_T;
              l_from_account VARCHAR2(32);
              l_to_account VARCHAR2(32);
              l_amount VARCHAR2(32);
              l_microTxTransaction MicroTxTransaction;
              l_forwardHeaders ForwardHeaders;
              l_is_withdraw_successful BOOLEAN;
              l_is_deposit_successful BOOLEAN;
              BEGIN
                  payload := JSON_OBJECT_T(:body);
                  l_from_account := payload.get_String(''from'');
                  l_to_account := payload.get_String(''to'');
                  l_amount := payload.get_String(''amount'');
      
                  -- Set response header
                  OWA_UTIL.mime_header(''application/json'', FALSE);
                  OWA_UTIL.http_header_close;
      
                  -- set forward headers
                  -- the bind variables are case sensitive
                  l_forwardHeaders := ForwardHeaders(:authorization, :tmmTxToken, :requestId);
      
                  -- tmm_begin_tx starts a global transaction that spans across multiple microservices.
                  -- It returns a MicroTxTransaction object which has the transaction metadata.
                  -- 60000 is the time, in milliseconds, for which the transaction remains active. 
                  -- If a transaction is not committed or rolled back within the specified time period, the transaction is rolled back.
                  l_microTxTransaction := tmm_begin_tx(l_forwardHeaders, 60000);
      
                  l_is_withdraw_successful := callWithdrawParticipant(l_from_account, l_amount, l_microTxTransaction , l_forwardHeaders);
                  IF NOT l_is_withdraw_successful THEN
                      tmm_rollback_tx(l_microTxTransaction, l_forwardHeaders);
                      :status_code := 500;
                      HTP.p(''{"error" : "Withdraw failed"}'');
                      RETURN;
                  END IF;
      
                  l_is_deposit_successful := callDepositParticipant(l_to_account, l_amount, l_microTxTransaction, l_forwardHeaders);
                  IF NOT l_is_deposit_successful THEN
                      tmm_rollback_tx(l_microTxTransaction, l_forwardHeaders);
                      :status_code := 500;
                      HTP.p(''{"error" : "Deposit failed"}'');
                      RETURN;
                  END IF;
      
                  -- Within global transaction
                  creditFundTransferRewards(l_from_account, l_amount);
      
                  tmm_commit_tx(l_microTxTransaction, l_forwardHeaders);
                  :status_code := 200;
                  HTP.P(''{"message":"Transfer successful"}'');
                  END;',
              p_items_per_page => 0);

    イニシエータ・アプリケーションがtmm_begin_tx()をコールした後、tmm_commit_tx()をコールする前に実行するすべての外部コールおよびDML文は、単一のグローバル・トランザクションの一部とみなされます。tmm_rollback_tx()がコールされた場合、アプリケーションはtmm_begin_tx()をコールした後、アプリケーションがtmm_commit_tx()をコールする前に実行されるすべての外部コールおよびDML文をロールバックします。

  3. イニシエータ・アプリケーションが作成する外部リクエストに対してリンク・ヘッダーを作成する必要があります。次の例は、linkという名前のリンク・ヘッダーを作成し、getTmmLinkHeader()関数をコールする方法を示しています。
    -- Specify the name for the link header
    p_name_01 => 'Link',
    p_value_01 => getTmmLinkHeader(l_microTxTransaction),

    ここで、l_microTxTransactionは、TMM_BEGIN_TX関数が返すMicroTxTransactionオブジェクトです。このオブジェクトには、トランザクション・メタデータが含まれます。

MicroTx PL/SQLライブラリ関数を使用するサンプルORDSトランザクション・イニシエータ・アプリケーションのソース・コードは、microtx-samples GitHubリポジトリのxa/plsql/databaseappフォルダにあるords_initiator_app.sqlファイルにあります。これは、MicroTxライブラリとアプリケーションの統合時に参照として使用できます。