Spring Transactions: Programmatic Transaction Management

1. Background

       In the last article Spring Transactions: Introduction to Transaction Properties and APIs, some properties and main APIs of Spring transactions were initially introduced. This article mainly discusses the programming history transaction management in Spring transactions.

 

2. Programmatic transaction management

1. Overview of Spring's programmatic transaction management

       Before Spring, programmatic transaction management was the only option for POJO-based applications. I have learned Hibernate before, and the transaction management here is to explicitly call beginTransaction(), commit(), rollback() and other transaction management related methods in the code, which is programmatic transaction management. Through the transaction management API provided by Spring, we can flexibly control the execution of transactions in the code. Under the hood, Spring still delegates transaction operations to the underlying persistence framework.

 

2. Programmatic transaction management based on the underlying API

       According to the three core interfaces of PlatformTransactionManager, TransactionDefinition and TransactionStatus, we can conduct transaction management programmatically. The sample code looks like this:

public class BankServiceImpl implements BankService {
    private BankDao bankDao;
    private TransactionDefinition txDefinition;
    private PlatformTransactionManager txManager;
    ......
    public boolean transfer(Long fromId, Long toId, double amount) {
        TransactionStatus txStatus = txManager.getTransaction(txDefinition);
        boolean result = false;
        try {
             result = bankDao.transfer(fromId, toId, amount);
             txManager.commit(txStatus);
        } catch (Exception e) {
             result = false;
             txManager.rollback(txStatus);
             System.out.println("Transfer Error!");
        }
        return result;
    }
}
The corresponding configuration file looks like this:
<bean id="bankService" class="footmark.spring.core.tx.programmatic.origin.BankServiceImpl">
   <property name="bankDao" ref="bankDao"/>
   <property name="txManager" ref="transactionManager"/>
   <property name="txDefinition">
      <bean class="org.springframework.transaction.support.DefaultTransactionDefinition">
         <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/>
      </bean>
   </property>
</bean>
       As shown above, we have added two properties to the class: one is a property of type TransactionDefinition, which is used to define a transaction; the other is a property of type PlatformTransactionManager, which is used to perform transaction management operations. If the method needs to implement transaction management, we first need to start a transaction before the method starts executing, and call the PlatformTransactionManager.getTransaction(...) method to start a transaction. After the transaction is created and started, you can start writing business logic code, and then perform the commit or rollback of the transaction where appropriate.

3. Programmatic transaction management based on TransactionTemplate

       Through the previous example, it can be found that this transaction management method is easy to understand, but the troublesome thing is that the code of transaction management is scattered in the business logic code, which destroys the organization of the original code, and each business method contains Similar boilerplate code for starting a transaction, committing/rolling back a transaction. Spring's very common template callback pattern in the data access layer is as follows:

public class BankServiceImpl implements BankService {
    private BankDao bankDao;
    private TransactionTemplate transactionTemplate;
    ......
    public boolean transfer(final Long fromId, final Long toId, final double amount) {
        return (Boolean) transactionTemplate.execute(new TransactionCallback(){
            public Object doInTransaction(TransactionStatus status) {
                Object result;
			try {
			     result = bankDao.transfer(fromId, toId, amount);
			} catch (Exception e) {
			     status.setRollbackOnly();
			     result = false;
			     System.out.println("Transfer Error!");
			}
                return result;
            }
        });
    }
}

 

The corresponding configuration files are as follows:

<bean id="bankService" class="footmark.spring.core.tx.programmatic.template.BankServiceImpl">
   <property name="bankDao" ref="bankDao"/>
   <property name="transactionTemplate" ref="transactionTemplate"/>
</bean>

       

       The execute() method of TransactionTemplate has a parameter of type TransactionCallback, which defines a doInTransaction() method. Usually, we implement the TransactionCallback interface as an anonymous inner class, and write business logic code in its doInTransaction() method. The default transaction commit and rollback rules can be used here, so that there is no need to explicitly call any transaction management API in the business code. The doInTransaction() method has a parameter of type TransactionStatus, and we can call the setRollbackOnly() method of this parameter anywhere in the method to mark the transaction as rolled back to perform transaction rollback.

According to the default rules, if an unchecked exception is thrown during the execution of the callback method, or the TransacationStatus.setRollbackOnly() method is explicitly called, the transaction is rolled back; if the transaction is completed or an exception of the checked type is thrown, then Commit the transaction.

        The TransactionCallback interface has a sub-interface TransactionCallbackWithoutResult, which defines a doInTransactionWithoutResult() method. The TransactionCallbackWithoutResult interface is mainly used for situations where no return value is required in the transaction process. Of course, for cases where no return value is required, we can still use the TransactionCallback interface and return any value in the method.

 

3. Summary

       This article mainly introduces the programmatic transaction management in Spring. The next article mainly introduces the declarative transaction management in Spring transaction. Interested partners can continue to read.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326778432&siteId=291194637