SoFunction
Updated on 2025-03-08

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

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

@Transactional(rollbackFor=) // indicates that Spring transaction is triggered when there is an exception in this method@Override
public CommonResult<User> saveUser(User user) {
    int insert = (user);
    try {
        // Add exception and catch        int a = 10/0;
    }catch (Exception e){
        ("Print exception message:"+e);
        return ("Server exception, transaction rollback");
    }
    if(insert > 0){
        return (user);
    }else {
        return ("Add failed");
    }
}

1. On an implementation method that adds information, we have added Spring transactions here.

2. Problem: One method reports an exception (int a = 10/0) ​​for exception capture, the other method will not roll back (insert add method)

What is this? It 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, all of which will be caught and "swallowed", resulting in the spring exception thrown triggering the transaction rollback strategy.

In layman's terms: the default spring transaction will only roll back when an uncaught runtimeexcetpion or error occurs.

2. Solution 1

spring aop exception catches and then rolls back. Add throw new runtimeexcetpion() at the end to catch, so that the program can be caught by aop and rolled back when abnormal. The disadvantage is that it cannot return the exception information prompt, and the front-end user interaction effect is poor

@Transactional(rollbackFor=)  // indicates that Spring transaction is triggered when there is an exception in this method@Override
public CommonResult<User> saveUser(User user) {
    int insert = (user);
    try {
        // Add exception and catch        int a = 10/0;
    }catch (Exception e){
        ("Exception message:"+e);
        // Scheme 1: spring aop exception capture        throw new RuntimeException();
    }
    if(insert > 0){
        return (user);
    }else {
        return ("Add failed");
    }
}

3. Solution 2

It is to let one method report an exception and the other method rollback, so that the Spring transaction rollback strategy can be truly triggered.

Added to the catch statement:

().setRollbackOnly(); //Manual rollback,This way, there is no need to handle exceptions on the upper layer

Complete code:

@Transactional(rollbackFor=) // indicates that Spring transaction is triggered when there is an exception in this method@Override
 public CommonResult<User> saveUser(User user) {
     int insert = (user);
     try {
         // Add exception and catch         int a = 10/0;
     }catch (Exception e){
         ("Exception message:"+e);
         // Plan 2: Manual rollback         ().setRollbackOnly();
         return ("Server exception, transaction rollback");
     }
     if(insert > 0){
         return (user);
     }else {
         return ("Add failed");
     }
 }

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

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

Just call the method

// Scheme 3: Public tool class Manual rollback();

Spring mvc: Try/catch failure caused by transactions

When testing an interface, I found a strange phenomenon:

This interface uses the @ResponseBody annotation to return json format data, and uses try/catch to include all logical codes. After debugging, it is found that there is no error in the return data, and it only contains an error prompt string caused by an exception. However, the chrome browser network shows that the http status code is 500.

Finally, I found that there is an annotation @Transactional on the RequestMapping method, which removes ok.

The above is personal experience. I hope you can give you a reference and I hope you can support me more.