6.7 About @Transactional

You can configure your Java applications that use the XA transaction protocol in two distinct ways.

  • By defining transaction boundaries explicitly
  • By using the @Transactional annotation

Each way offers its own advantages.

@Transactional Annotation

When you use the @Transactional annotation, you only need to provide the business logic. You don't need to define the transaction boundaries. Only if there is an exception, the transaction is rolled back. In all other scenarios, the transaction is committed.

The following code samples demonstrate the usage of the @Transactional annotation. Annotate the existing transfer method that defines the application business logic with @Transactional. The transfer method calls the withdraw method to debit an amount from participant service 1 and the deposit method to credit an amount to participant service 2. Note that you only have to define the application's business logic in this case.

Sample Code for a JAX-RS Application Using @Transactional

import javax.transaction.Transactional;
...//some code
@Transactional(value = Transactional.TxType.REQUIRED)
transfer(){
    // 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 JAX-RS apps, see https://docs.oracle.com/javaee/7/api/javax/transaction/Transactional.html.

Sample Code for a Spring REST Application Using @Transactional

import org.springframework.transaction.annotation.Transactional;
...//some code
  @Transactional(propagation = Propagation.REQUIRED)
  
transfer(){
    // 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.

Define the Transaction Boundaries

Sample Code for a JAX-RS Application that Defines Transaction Boundaries

Sample Code for a JAX-RS Application that Defines Transaction Boundaries

When you want to specify certain conditions under which you want to commit or roll back a transaction, you can define the transaction boundaries. Use the begin() and commit() or rollback() methods to define the transaction boundaries. You must provide code to define the beginning of the transaction boundary and also provide the business logic to decide when to commit or rollback a transaction. This provides a lot of flexibility to define the scenarios in which the transaction is committed or rolled back.

The following samples shows the transfer method, which in turn calls the withdraw method to debit an amount from participant service 1 and the deposit method to credit an amount to participant service 2. Note that you only have to define the transaction boundaries and the application's business logic in this case.

Create and handle the TrmUserTransaction object.

transfer() {
    //Application-specific business logic
    TrmUserTransaction transaction = new TrmUserTransaction();
    //Starts a transaction. This is where the transaction boundary begins.
    transaction.begin();
    // code that is specific to the application's business logic
    // withdraw operation on participant service 1    
    isWithdrawSuccessful = withdraw();
    if(!isWithdrawSuccessful){
        transaction.rollback();
    }
    // deposit operation on participant service 2
    isDepositSuccessful = deposit();
    if(!isDepositSuccessful){
        transaction.rollback();
    }
    transaction.commit();
    //When you commit or rollback a transaction, the transaction boundary ends.
    //Application-specific business logic
}

Create and handle the MicroTxUserTransactionService object.

// Autowire the MicroTx transaction service
@Autowired
MicroTxUserTransactionService microTxtransaction;

transfer() {
    try {
        //Starts a transaction. This is where the transaction boundary begins.
        microTxtransaction.begin();
        // code that is specific to the application's business logic
        // withdraw operation on participant service 1
        isWithdrawSuccessful = withdraw();
    
        if(!isWithdrawSuccessful){
            microTxtransaction.rollback();
        }
        // deposit operation on participant service 2
        isDepositSuccessful = deposit();
        if(!isDepositSuccessful){
            microTxtransaction.rollback();
        }
        microTxtransaction.commit();
        //When you commit or rollback a transaction, the transaction boundary ends.
        //Application-specific business logic
    } catch (Exception ex) {
        microTxtransaction.rollback();
        // Handle exception
    }
}

All code examples in this guide define the transaction boundary.