6.10.2 Configure Spring REST 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 Spring Boot 3.x application based on Spring REST as a transaction initiator:
  1. Specify property values for the MicroTx library. See Configure Library Properties for Spring REST Apps.
  2. Include only one of the following MicroTx library files as a maven dependency in the Spring Boot 3.x application's pom.xml file. The following sample code is for the 24.2 release. Provide the correct version, based on the release version that you want to use. Spring Boot 3.x applications work with Java 17.
    • For JDBC applications, use the microtx-spring-boot-starter file.

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter</artifactId>
           <version>24.2</version>
      </dependency>
    • For Java Apps that use Hibernate as JPA provider, use the microtx-spring-boot-starter-hibernate library file.

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter-hibernate</artifactId>
           <version>24.2</version>
      </dependency>
    • For Java Apps that use EclipseLink as JPA provider, use the microtx-spring-boot-starter-eclipselink library file.

      <dependency>
           <groupId>com.oracle.microtx</groupId>
           <artifactId>microtx-spring-boot-starter-eclipselink</artifactId>
           <version>24.2</version>
      </dependency>
  3. Complete the following steps if you want to use the @Transactional annotation. See About @Transactional.
    1. Import the org.springframework.transaction.annotation.Transactional package.
      import org.springframework.transaction.annotation.Transactional;
    2. Annotate the method which initiates the transaction with @Transactional. The following code sample demonstrates the usage of @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
          }
      

      For details about using @Transactional for Spring REST apps, see https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Transactional.html.

    3. Skip to step 8 as you don't have to specify the transaction boundaries using begin(), commit(), and rollback() when you use @Transactional.
  4. Import the com.oracle.microtx.xa.rm.MicroTxUserTransactionService package.
    import com.oracle.microtx.xa.rm.MicroTxUserTransactionService;
  5. Autowire the MicroTxUserTransactionService class before your application logic initiates or begins a transaction.
    @Autowired
    MicroTxUserTransactionService microTxUserTransactionService;
  6. Within the application code that initiates the transaction, demarcate the transaction boundaries, such as to begin, commit, or roll back the transactions. The following code sample demonstrates how to begin a new XA transaction.
    • If your application only initiates the transaction and does not participate in the transaction, add the following line to your application code to begin the XA transaction.

      
      microTxUserTransactionService.begin();
      ... // Implement the business logic to begin a transaction.
    • If your application initiates the transaction and participates in it, add the following line to your application code to begin the XA transaction.

      
      microTxUserTransactionService.begin(true);
      ... // Implement the business logic to begin a transaction.
      
  7. Based on your business logic, commit or rollback the transaction.
    • To commit a transaction:

      microTxUserTransactionService.commit();
    • To rollback a transaction:

      microTxUserTransactionService.rollback();

    The following code sample demonstrates how you can demarcate the transaction boundaries using begin(), commit(), and 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. Use a WebClient or the REST template to call the endpoints of the transaction participant services to perform the transaction. The transaction initiator service begins the transaction. To complete the transaction, the initiator service may have to make calls to one or more participant services. While calling the participant services, use the object that you create.
    • @Autowired
      @Qualifier("MicroTxXaWebClientBuilder")
      WebClient.Builder webClientBuilder;
    • Inject the Spring Boot REST template provided by MicroTx as shown in the following sample code.
      @Autowired
      @Qualifier("MicroTxXaRestTemplate")
      RestTemplate restTemplate;
  9. Save your changes.
Source code of a sample Spring REST transaction initiator application which uses the MicroTx library and XA is available in the teller-spring folder which is located in the microtx-samples GitHub repository. You can use this as a reference while integrating the MicroTx libraries with your application. This provides an example of how you can use the MicroTx Spring REST libraries with the business logic of your Spring REST initiator application. This sample application is called Teller. It initiates a transaction between two departments. It calls Dept A to withdraw an amount and it calls Dept B to deposit the amount.
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 Spring REST App as Transaction Participant. The teller-as-participant-spring folder which is located in the microtx-samples GitHub repository provides the source code of a Spring REST transaction initiator application which also participates in the transaction.