6.12.6 Configure ORDS App as Transaction Participant

  1. Specify property values for the MicroTx library. See Configure PL/SQL Library Properties for ORDS Apps.
  2. Create DDLs for tables and other database objects required for your application.
  3. Add required DMLs to insert default data.
  4. Create or define a new REST module for your application.
  5. Create the required PL/SQL functions and stored procedures for your application.
  6. 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 accounts as a value. Replace this value with information that is specific to your environment.
      DECLARE
          //Provide a name for the REST service module
          restModuleName VARCHAR2(256):= 'accounts'; 
          //Provide a base path for the REST service
          restModuleBasePath VARCHAR2(256):= 'accounts';
    2. Set value for the l_callBackUrl. For example, http://localhost:50080/ords/ordstest/accounts. Also initialize parameters for TmmReturn.
      DECLARE
      //Set up the callBackUrl correctly. This is generally the base URL or path of the module.
      l_callBackUrl  VARCHAR2(256) := OWA_UTIL.get_cgi_env(''X-APEX-BASE'') || ''accounts'';
      l_tmmReturn TmmReturn;
      l_tmmReturn2 TmmReturn;
    3. Call TmmStart.

      The following code sample demonstrates how you can call the TmmStart function. Pass all the parameters as shown in the following example. You must pass the value for the l_callBackUrl when you call TmmStart. The values of all the other parameters are automatically obtained from the incoming request headers and passed.

      //Call TmmStart. Specify value for callBackUrl.
      l_tmmReturn := TmmStart(callBackUrl => l_callBackUrl, linkUrl => :linkUrl, requestId => :requestId, authorizationToken => :authorization, tmmTxToken => :tmmTxToken);

      The TmmStart function returns an object, which provides an attribute, proceed, that indicates whether the TmmStart function was successfully executed and that the transaction can proceed ahead.

    4. Check if the XA transaction should proceed further (value of l_tmmReturn.proceed is greater than 0) or not (value of l_tmmReturn.proceed is 0). Execute your business logic only if the XA transaction can proceed further, otherwise the TmmStart function must return a HTTP error status code as shown in the following code sample. Call the TmmEnd function after the business logic has been completely executed.
      IF (l_tmmReturn.proceed > 0) THEN                  
      //Execute your business logic only if the XA transaction can proceed further.
      //Execute SQLs statements or call other functions or stored procedures.
      	doWithdraw(p_amount  => :amount, p_account_id  => :accountId);
       
      	//Call TmmEnd at the end of the REST function.
      	l_tmmReturn2 := TmmEnd(p_xid => l_tmmReturn.xid);      
              :status_code := 200;
      ELSE
              :status_code := 400; --bad request
      END IF;
    5. Create MicroTx callback APIs.
      createTMMCallbacks(moduleName => restModuleName);
    6. Register all the method handlers that will participate in the XA transaction.
      registerXaHandler(moduleName => restModuleName,
                            handlerPattern => ':accountId/withdraw',
                            handlerMethod => 'POST');

    The following code sample demonstrates how you can implement the handler.

    DECLARE
        //Provide a name for the REST service module
        restModuleName VARCHAR2(256):= 'accounts'; 
        //Provide a base path for the REST service
        restModuleBasePath VARCHAR2(256):= 'accounts';
    
    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        => ':accountId/withdraw');
     
        ORDS.define_handler(
                p_module_name    => restModuleName,
                p_pattern        => ':accountId/withdraw',
                p_method         => 'POST',
                p_source_type    => ORDS.source_type_plsql,
                p_source         => '
                            DECLARE
                            //Set up the callBackUrl correctly. This is generally the base URL or path of the module.
                            //Example: http://localhost:50080/ords/ordstest/accounts
                            l_callBackUrl  VARCHAR2(256) := OWA_UTIL.get_cgi_env(''X-APEX-BASE'') || ''accounts''; 
                            l_tmmReturn TmmReturn;
                            l_tmmReturn2 TmmReturn;
     
                            BEGIN
                                //Call TmmStart. Pass all the other parameters than the callBackUrl.
                                l_tmmReturn := TmmStart(callBackUrl => l_callBackUrl, linkUrl => :linkUrl, requestId => :requestId, authorizationToken => :authorization, tmmTxToken => :tmmTxToken);
     
                                //Check if the transaction should proceed further
                                //(value of l_tmmReturn.proceed is greater than 0) 
                                //or not (value of l_tmmReturn.proceed is 0). 
                                //Execute your business logic only if transaction can proceed further.
                                //If not, then return with an HTTP error code.
                                IF (l_tmmReturn.proceed > 0) THEN                  
     
                                    //Execute your business logic. 
                                    //Execute SQLs statements or call other functions or stored procedures.
                                    doWithdraw(p_amount  => :amount, p_account_id  => :accountId);
     
                                    //Call TmmEnd at the end of the REST function.
                                    l_tmmReturn2 := TmmEnd(p_xid => l_tmmReturn.xid);      
     
                                    :status_code := 200;
     
                                ELSE
                                    :status_code := 400; --bad request
     
                                END IF;
     
                            exception
                                when others then
                                    :status_code := 500;
     
                             END;',
                p_items_per_page => 0);
     
     
        //Create MicroTx callback APIs.
        createTMMCallbacks(moduleName => restModuleName);
     
        //Register all method handlers that will participate in the XA transaction.
        registerXaHandler(moduleName => restModuleName,
                          handlerPattern => ':accountId/withdraw',
                          handlerMethod => 'POST');
     
    COMMIT;
    END;
    /
Source code of an ORDS transaction participant application which uses the MicroTx PL/SQL library functions is available in xa/plsql/databaseapp/ords_participant_app.sql in the microtx-samples GitHub repository. You can use this as a reference while integrating the MicroTx libraries with your application.