在Service中抛出异常事务未回滚问题分析与解决
1.问题提出:
在service中写方法时,抛出了一个Exception, 本来目的是为了让事务回滚, 但事实上没有回滚,产生了脏数据。
代码如下:
@Override
@Transactional
public void insertInSingle(String type, MobileEditInDTO dto) throws Exception {
MaterialOtherInSingle otherInSingle = otherInService.findEntityByProperty("tableNo", tableNo);
//其他入库单表头
otherInSingle.setServiceTypeID(serviceTypeService.getServiceType(dto.getServiceTypeId()));
otherInSingle.setInCome(storageTypeService.getStorageType(dto.getStorageTypeId()));
otherInSingle.setInStorageDate(dto.getInDate());
throw new Exception(111);
}
在这个方法中用hql获得了一个持久态对象,并设置了新的属性,在最后演示的时候抛出了异常,但是最后并未回滚。
2.问题分析
在这个方法中加入了@Transactional注解,声明了这是一个事务,其原理就是AOP。平时我们都是这么做的,但是并不是很清楚原理是什么。
注解其实只是一个声明,真正的目的在声明之后这个方法成为了一个连接点,说到连接点又不得不说AOP,
AOP说简单点其实就是一个动态代理,我们service之所以要先声明接口再有一个实现类其实很大程度上为了实现动态代理,实现动态代理之后我们可以省去很多在方法层面上重复的代码。
不理解的请自行百度关键词: AOP, 动态代理,这个东西很复杂一下子也说不清楚(其实我也不是很懂)。
说回来这个@Transactional,它的切入点(PointCut)其实就是抛异常,在抛出异常的时候调用增强处理(Advice)中的方法将事务回滚掉,但是这个抛异常抛的不是普通的自Exception中继承过来的异常,
unchecked exception回滚。也就是默认对RuntimeException()异常或是其子类进行事务回滚。虽然RuntimeException继承自Exception,但是切入点要更具体一些。
当然如果要让所有Exception都回滚,在@Transactional(rollbackFor = Exception.class) 上加个参数就好了。
但是要注意的事,如果声明了@Transactional,但是又在方法里面自己捕获了异常,也就是try catch掉了,那就不会回滚了,因为切入点根本没捕获到,也谈不上调用增强处理中的方法了。
3.问题解决
上面啰嗦了这么多,解决这个问题无非就是两个办法:
1.抛出RuntimeException
2.抛出Exception,同时在事务声明中加上@Transactional(rollbackFor = Exception.class)
如果有写到不对的地方,欢迎多多指正
还要再说明一点,在controller中调用service的这个已经解决的方法是可以try catch的,不用担心不会回滚,因为已经被aop监听到了。
在Service中抛出异常事务未回滚问题分析与解决的更多相关文章
- SSM框架中,事务无法回滚的原因和解决
原因: 由ServletContextListener加载spring配置文件产生的是父容器,springMVC产生的是子容器,子容器对Controller进行扫描装配时装配了@Service注解的实 ...
- Spring事务不回滚原因分析
Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离. 在我完成一个项目的时候,遇到了一个Spring事务不回滚的问题,通过aspectJ和@Transacti ...
- [存储过程]中的事务(rollback)回滚
在编写SQL Server 事务相关的存储过程代码时,经常看到下面这样的写法: begin tran update statement 1 ... update statement 2 ... del ...
- Spring3声明式事务处理事务无法回滚rollback分析(annotation与xml配置混用)
新项目试运行,DBA提示生产数据库一个表的事务20分钟都未提交,分析过程如下: 1.查看日志log文件,最近20分钟是否有error日志: 2.发现某表有insert错误日志,初步判断由该表插入异常, ...
- Spring声明式事务不回滚问题
疑问,确实像往常一样在service上添加了注解 @Transactional,为什么查询数据库时还是发现有数据不一致的情况,想想肯定是事务没起作用,出现异常的时候数据没有回滚.于是就对相关代码进行了 ...
- springmvc mybatis 声明式事务管理回滚失效,(checked回滚)捕捉异常,传输错误信息
一.知识点及问题 后端框架: Spring .Spring mvc .mybatis 业务需求: client先从服务端获取用户大量信息到client,编辑完毕之后统一Post至服务端,对于数据的改动 ...
- spring + myBatis 常见错误:注解事务不回滚
最近项目在用springMVC+spring+myBatis框架,在配置事务的时候发现一个事务不能回滚的问题. 刚开始配置如下:springMVC.xml配置内容: spring.xml配置内容 从上 ...
- spring事务——try{...}catch{...}中事务不回滚的几种处理方式
当希望在某个方法中添加事务时,我们常常在方法头上添加@Transactional注解 @ResponseBody @RequestMapping(value = "/payment" ...
- spring事务——try{...}catch{...}中事务不回滚的几种处理方式(转载)
转载自 spring事务——try{...}catch{...}中事务不回滚的几种处理方式 当希望在某个方法中添加事务时,我们常常在方法头上添加@Transactional注解 @Respon ...
随机推荐
- 10分钟入门kubernetes(上)
kubernetes简称k8s, 主要用途是automate deployment, scaling, and managment of containerized applications.是目前非 ...
- Mongodb基础与入门
一:基本了解 1. 特点 基于分布式文件存储的NoSql数据库.能为WEB应用提供可扩展的高性能数据存储解决方案. ...
- mongodb的TTL索引介绍(超时索引)
TTL索引是mongodb新支持的用于延时自动删除记录的一种索引.它仅包含一个字段,该字段值需要是Date()类型,并且不支持复合索引.可以指定某条记录在延时固定时间后自动删除.数据自动超时删除主要用 ...
- SpringMvc自动装配@Controller无效
1.问题原因:SpringMvc驱动器没有扫描该Controller层 虽然配置了 <!-- 启用spring mvc 注解 --> <context:annotation-conf ...
- Java采用内部构造器Builder模式进行对类进行构建
好处: 能保证重叠构造器模式的安全性: 能保证JAVABeans模式的可读性: package cn.lonecloud.builder; /** * 使用内部类构建器来对这个类进行构造 * @Tit ...
- HDU - 1172
思路:假设答案是x,那么x必定满足所有语句给定的条件.例如3585和4815就有2个相同的数,1和相同的位. 只要这个数满足所有条件,那么就是一个可能的答案,当答案数量超过1个时,就是"No ...
- SpringBoot项目在IntelliJ IDEA中实现热部署
spring-boot-devtools是一个为开发者服务的一个模块,其中最重要的功能就是自动应用代码更改到最新的App上面去.原理是在发现代码有更改之后,重新启动应用,但是速度比手动停止后再启动更快 ...
- 将FTP映射至Windows
在经常使用ftp传输文件的环境中,每次上传和下载文件都需要重新连接然后登录是非常繁琐的一件事情.我们可以将FTP空间映射到本地磁盘空间,免去输入地址以及账号.密码.方便我们日常中文件的上传和下载. 1 ...
- 远程控制你的智能电视,按键|输入|安装App等都已实现,已开源!
一.序 Hi,大家好,我是承香墨影! 智能电视或者智能盒子,不知道大家了解多少? 这两年各大厂商生产的电视设备,基本上都是搭载的 Android 系统.既然电视本身就是 Android 系统的,我们也 ...
- javascript对象(简略)
javascript对象有着自有的属性,对象可以从一个称为原型的对象继承属性,对象的方法通常是继承的属性,原型式继承是javascript的核心特征.