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.