解决try-catch捕获异常信息后Spring事务失效的问题
作者:DT辰白 发布时间:2022-11-15 03:17:33
标签:try-catch,异常,Spring事务
一、首先在Spring Boot项目中,手动添加异常方法进行测试
@Transactional(rollbackFor=Exception.class) //表示此方法有异常时触发Spring事务
@Override
public CommonResult<User> saveUser(User user) {
int insert = baseMapper.insert(user);
try {
// 添加异常,并进行捕获
int a = 10/0;
}catch (Exception e){
logger.info("打印异常信息:"+e);
return CommonResult.commentFailure("服务器异常,事务回滚");
}
if(insert > 0){
return CommonResult.commentSuccess(user);
}else {
return CommonResult.commentFailure("添加失败");
}
}
1、一个添加信息的实现类方法上,此处我们加了Spring的事务。
2、问题:一个方法报异常(int a = 10/0)进行了异常捕获,另一个方法不会回滚(insert添加方法)
这是什么情况呢,相当于Spring事务策略失效了。
try-catch捕获了异常后,这种业务方法也就等于脱离了spring事务的管理,因为没有任何异常会从业务方法中抛出,全被捕获并“吞掉”,导致spring异常抛出触发事务回滚策略失效。
通俗的来说:默认spring事务只在发生未被捕获的 runtimeexcetpion或error时才回滚。
二、处理方案一
spring aop 异常捕获进而回滚。在catch中最后加上throw new runtimeexcetpion(),这样程序异常时才能被aop捕获进而回滚,缺点是无法return异常信息提示,前端用户交互效果不佳
@Transactional(rollbackFor=Exception.class) //表示此方法有异常时触发Spring事务
@Override
public CommonResult<User> saveUser(User user) {
int insert = baseMapper.insert(user);
try {
// 添加异常,并进行捕获
int a = 10/0;
}catch (Exception e){
logger.info("异常信息:"+e);
// 方案一:spring aop 异常捕获
throw new RuntimeException();
}
if(insert > 0){
return CommonResult.commentSuccess(user);
}else {
return CommonResult.commentFailure("添加失败");
}
}
三、处理方案二
就是让一个方法报异常,另一个方法回滚,这样才能真正的触发Spring事务回滚策略。
catch语句中增加:
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚,这样上层就无需去处理异常了
完整代码:
@Transactional(rollbackFor=Exception.class) //表示此方法有异常时触发Spring事务
@Override
public CommonResult<User> saveUser(User user) {
int insert = baseMapper.insert(user);
try {
// 添加异常,并进行捕获
int a = 10/0;
}catch (Exception e){
logger.info("异常信息:"+e);
// 方案二:手动回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return CommonResult.commentFailure("服务器异常,事务回滚");
}
if(insert > 0){
return CommonResult.commentSuccess(user);
}else {
return CommonResult.commentFailure("添加失败");
}
}
四、如过需要手动进行手动回滚的业务方法比较多,我们可以写一个公共的工具类
SpringRollBackUtil.java
public class SpringRollBackUtil {
/**
* 事务回滚机制
*/
public static void rollBack() {
try {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
} catch (Exception e) {
e.printStackTrace();
}
}
}
只需调用方法即可
// 方案三:公共工具类 手动回滚
SpringRollBackUtil.rollBack();
Spring mvc:事务引起的try/catch失效
在测试一个接口时,发现一个奇怪的现象:
该接口使用@ResponseBody注解返回json格式数据,并且使用try/catch包括全部逻辑代码,debug后发现返回数据没有任何错误,只包含一段因产生异常导致的错误提示字符串,但是chrome浏览器network却显示http状态码为500。
最后发现在该RequestMapping方法上还有一个注解@Transactional,去除ok。
来源:https://blog.csdn.net/qq_41107231/article/details/106698940
0
投稿
猜你喜欢
- 本文实例讲述了Android编程之消息机制。分享给大家供大家参考,具体如下:一、角色描述1.Looper: 一个线程可以产生一个Looper
- 如下所示:public static String reThreeStr(String ss){boolean result= ss.mat
- 1、导包基于maven<dependency> <groupId>com.fasterxml.jacks
- 最近在开发的过程中,一个列表的查询,涉及到了多表的关联查询,由于持久层使用的是mongodb,对这个非关系型数据使用的不是很多,所以在实现此
- 在导入studio工程的时候,进行sync的时候,提示Error:Configuration with name 'default&
- 工作中有做过手机App项目,前端和android或ios程序员配合完成整个项目的开发,开发过程中与ios程序配合基本没什么问题,而andro
- 我们主要介绍一下:java中如何通过最简单的方式实现链式创建json对象,解决创建json代码臃肿的问题。1、假设我们要创建一个json对象
- java的构造函数是一个非常重要的作用,首先java里的构造函数是可以重载的,而且因为也是可以继承在父类的构造函数,所以在子类里,首先必然是
- Spring Cloud 为开发人员提供了一系列的工具来快速构建分布式系统的通用模型 。例如:配置管理、服务发现、断路由、智能路由、微代理、
- 实现HandlerInterceptor接口或者继承HandlerInterceptor的子类,比如Spring 已经提供的实现了Handl
- 在常见场景下:返回数据建议使用map,不建议使用实体对象 /** * 1. 名字包含雨并且年龄小于40  
- Result也是Struts2比较重要的一部分,在Result的配置中常用的有四种类型:dispatcher、redirect、chain和
- 这篇文章主要介绍了springboot如何使用AOP做访问请求日志,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价
- Spring对配置类的处理主要分为2个阶段配置类解析阶段会得到一批配置类的信息,和一些需要注册的beanbean注册阶段将配置类解析阶段得到
- 引言在高并发的场景下,异步是一个极其重要的优化方向。前段时间,生产环境发生一次事故,笔者认为事故的场景非常具备典型性 。写这篇文章,笔者想和
- 前提在日常使用SpringMVC进行开发的时候,有可能遇到前端各种类型的请求参数,这里做一次相对全面的总结。SpringMVC中处理控制器参
- yaml语法注解配置文件两种形式application.properties和.yaml第一种语法 key=value第二种key:空格va
- 什么是ByteBuddyByteBuddy是一个java的运行时代码生成库,他可以帮助你以字节码的方式动态修改java类的代码。为什么需要B
- 下载maven 解压路径: 打开环境变量:右键此电脑-属性-高级系统设置-高级-环境变量添加以下系统变量:测试:win+
- 适配器(Adapter)模式:适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一