6.11.1 Configure Node.js App as Transaction Initiator

A transaction initiator service initiates or starts a transaction. Based on your application's business logic, a transaction initiator service may only start the transaction or start the transaction and participate in the transaction as well.

Before you begin, identify if your application only initiates the transaction or initiates and participates in the transaction. Configure your application accordingly as the requirements vary slightly for the two scenarios.

Let us consider two scenarios to understand if your application only initiates the transaction or participates in the transaction as well.
  • Scenario 1: A banking teller application transfers an amount from one department to another. Here, the teller application only initiates the transaction and does not participate in it. Based on the business logic, the teller application calls different services to complete the transaction. A database instance may or may not be attached to the teller application.
  • Scenario 2: A banking teller application transfers an amount from one department to another. For every transaction, the teller application charges 1% as commission. Here, the teller application initiates the transaction and participates in it. A database instance must be attached to the teller application to save the transaction information.
To configure your Node.js application as a transaction initiator:
  1. Add the MicroTx library for Node.js as a dependency in the package.json file. The library file is located in the installation_directory/otmm-RELEASE/otmm/nodejs folder.
    "dependencies": {
        "tmmlib-node": "file:oracle-microtx-1.0.0.tgz"
      }
  2. Configure the property values for the MicroTx library. See Configure Library Properties. To enable logging for Node.js applications, you must set additional properties. See Enable Logs for MicroTx Node.js Library.
  3. Configure the MicroTx library properties for the microservice by passing the tmm.properties file in which you have defined the values.
    TrmConfig.init('./tmm.properties');
  4. Edit the application code to:
    1. Create a TrmUserTransaction object.
    2. To begin a transaction, call begin() on the TrmUserTransaction object that you have created. The parameters that you pass when you call begin() depend on whether your application only initiates the transaction or also participates in it.
    3. To commit or rollback the transaction, call commit() or rollback() on the TrmUserTransaction object that you have created.

    The following example shows how to create a TrmUserTransaction object named ut, and then begin, commit or rollback a transaction. Here req represents the request.

    //Step 3(a): Create a TrmUserTransaction object
    let ut: TrmUserTransaction = newTrmUserTransaction();
    try {
      //Step 3(b): Transaction demarcation - (start)
      await ut.begin(req);  //If your application only initiates the transaction and does not participate in it.
      await ut.begin(req, true);  //If your application initiates the transaction and participates in it.
    
      ... // implement business logic
      
      await ut.commit(req); //Step 3(c): Transaction demarcation - commit (end)
    
      resp.status(200).send("Transaction complete.");
    } 
    catch (e) {
      console.log("Transaction Failed: ", e);
      let message = e.message;
      try {
        console.log("Rollback on transaction failure.");
        await ut.rollback(req); //Step 3.c: Transaction rollback (end)
        message = message + ". Transaction rolled back. ";
      } catch (ex) {
        console.log("Error in rollback for transfer failure: ", ex);
      }
      resp.status(500).send(message);
    }

    The example code is implemented in a try-catch statement, so that errors, if any, are handled gracefully. You can also implement your sample code without using a try-catch statement.

  5. Save the changes, and then deploy your application. See Deploy Your Application.
If the initiator service also participates in the transaction in addition to initiating the transaction, you must make additional configurations for the application to participate in the transaction and communicate with the resource manager. See Configure Node.js App as Transaction Participant.