6.14.5 Configure ORDS App as Transaction Initiator

  1. Specify property values for the MicroTx library. See Configure PL/SQL Library Properties for ORDS Apps.
  2. For every REST API, define a template and a handler.
    1. Enter a name and base path for the REST service module. The following code example provides teller and transfers as values. Replace these values with information that is specific to your environment.
      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. Define a module, and then define a template for the module.
      
      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. Provide source code for the module. The following code snippet demonstrates how you can define transaction boundaries by using the MicroTx PL/SQL library functions, tmm_begin_tx(), tmm_rollback_tx(), and tmm_commit_tx(). When you begin a transaction, it returns a MicroTxTransaction object. You will use this returned object to commit or roll back the global transaction. For reference information about the PL/SQL functions, see MicroTx PL/SQL Library Functions.
      
      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.
                  l_microTxTransaction := tmm_begin_tx(l_forwardHeaders);
      
                  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);

    All the external calls and DML statements that an initiator application runs after calling tmm_begin_tx() and before calling tmm_commit_tx() is considered as part of a single global transaction. In case tmm_rollback_tx() is called, it rolls back all external calls and DML statements that are executed after the application calls tmm_begin_tx() and before the application calls tmm_commit_tx().

  3. You must create a link header for any external requests that the initiator application makes. The following example demonstrates how you can create a link header with the name link, and then call the getTmmLinkHeader() function.
    -- Specify the name for the link header
    p_name_01 => 'Link',
    p_value_01 => getTmmLinkHeader(l_microTxTransaction),

    Where, l_microTxTransaction is the MicroTxTransaction object that the TMM_BEGIN_TX function returns. This object contains the transaction metadata.

Source code of a sample ORDS transaction initiator application which uses the MicroTx PL/SQL library functions is available in the ords_initiator_app.sql file which is located in the xa/plsql/databaseapp folder in the microtx-samples GitHub repository. You can use this as a reference while integrating the MicroTx libraries with your application.