Solve the problem of Spring transaction failure after try catch captures exception information

  • 2021-09-24 22:28:21
  • OfStack

1. First, in the Spring Boot project, manually add exception methods for testing


@Transactional(rollbackFor=Exception.class) // Indicates that this method is triggered when there is an exception Spring Affairs 
@Override
public CommonResult<User> saveUser(User user) {
    int insert = baseMapper.insert(user);
    try {
        //  Add exceptions and catch them 
        int a = 10/0;
    }catch (Exception e){
        logger.info(" Print exception information: "+e);
        return CommonResult.commentFailure(" Server exception, transaction rollback ");
    }
    if(insert > 0){
        return CommonResult.commentSuccess(user);
    }else {
        return CommonResult.commentFailure(" Add failed ");
    }
}

1, 1 to add information to the implementation class method, where we add Spring transactions.

2. Problem: One method reported exception (int a = 10/0) and caught exception, and the other method did not roll back (insert added method)

What is this situation, which is equivalent to the failure of Spring transaction policy.

After try-catch catches exceptions, this business method is equivalent to breaking away from the management of spring transactions, because no exceptions will be thrown from the business method, and all of them will be caught and "swallowed", which leads to the failure of the transaction rollback strategy triggered by spring exception throwing.

Generally speaking, the default spring transaction is rolled back only when an uncaptured runtimeexcetpion or error occurs.

2. Treatment Scheme 1

spring aop exception catch and then rollback. throw new runtimeexcetpion () is added to catch, so that the program can be caught and rolled back by aop when it is abnormal. The disadvantage is that it can't prompt return abnormal information, and the front-end user interaction effect is not good


@Transactional(rollbackFor=Exception.class)  // Indicates that this method is triggered when there is an exception Spring Affairs 
@Override
public CommonResult<User> saveUser(User user) {
    int insert = baseMapper.insert(user);
    try {
        //  Add exceptions and catch them 
        int a = 10/0;
    }catch (Exception e){
        logger.info(" Exception information: "+e);
        //  Program 1 : spring aop  Exception trapping 
        throw new RuntimeException();
    }
    if(insert > 0){
        return CommonResult.commentSuccess(user);
    }else {
        return CommonResult.commentFailure(" Add failed ");
    }
}

3. Treatment Scheme 2

It is to let one method report an exception and the other method roll back, so as to really trigger the Spring transaction rollback strategy.

Add to the catch statement:


TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); // Manual rollback, so that the upper layer does not have to handle exceptions 

Complete code:


@Transactional(rollbackFor=Exception.class) // Indicates that this method is triggered when there is an exception Spring Affairs 
@Override
 public CommonResult<User> saveUser(User user) {
     int insert = baseMapper.insert(user);
     try {
         //  Add exceptions and catch them 
         int a = 10/0;
     }catch (Exception e){
         logger.info(" Exception information: "+e);
         //  Program 2 Manual rollback 
         TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
         return CommonResult.commentFailure(" Server exception, transaction rollback ");
     }
     if(insert > 0){
         return CommonResult.commentSuccess(user);
     }else {
         return CommonResult.commentFailure(" Add failed ");
     }
 }

4. If there are many business methods that need manual rollback, we can write a public tool class

SpringRollBackUtil.java


public class SpringRollBackUtil {
    /**
     *  Transaction rollback mechanism 
     */
    public static void rollBack() {
        try {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Just call the method


//  Program 3 Common tool classes   Manual rollback 
SpringRollBackUtil.rollBack();

Spring mvc: try/catch failures due to transactions

When testing an interface, I found a strange phenomenon:

The interface uses @ ResponseBody annotation to return json format data, and uses try/catch to include all logical codes. After debug, it is found that the returned data has no errors, only contains one error prompt string caused by exception, but http browser network shows that http status code is 500.

Finally, it is found that there is another annotation @ Transactional on the RequestMapping method, removing ok.


Related articles: