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中抛出异常事务未回滚问题分析与解决的更多相关文章

  1. SSM框架中,事务无法回滚的原因和解决

    原因: 由ServletContextListener加载spring配置文件产生的是父容器,springMVC产生的是子容器,子容器对Controller进行扫描装配时装配了@Service注解的实 ...

  2. Spring事务不回滚原因分析

    Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离. 在我完成一个项目的时候,遇到了一个Spring事务不回滚的问题,通过aspectJ和@Transacti ...

  3. [存储过程]中的事务(rollback)回滚

    在编写SQL Server 事务相关的存储过程代码时,经常看到下面这样的写法: begin tran update statement 1 ... update statement 2 ... del ...

  4. Spring3声明式事务处理事务无法回滚rollback分析(annotation与xml配置混用)

    新项目试运行,DBA提示生产数据库一个表的事务20分钟都未提交,分析过程如下: 1.查看日志log文件,最近20分钟是否有error日志: 2.发现某表有insert错误日志,初步判断由该表插入异常, ...

  5. Spring声明式事务不回滚问题

    疑问,确实像往常一样在service上添加了注解 @Transactional,为什么查询数据库时还是发现有数据不一致的情况,想想肯定是事务没起作用,出现异常的时候数据没有回滚.于是就对相关代码进行了 ...

  6. springmvc mybatis 声明式事务管理回滚失效,(checked回滚)捕捉异常,传输错误信息

    一.知识点及问题 后端框架: Spring .Spring mvc .mybatis 业务需求: client先从服务端获取用户大量信息到client,编辑完毕之后统一Post至服务端,对于数据的改动 ...

  7. spring + myBatis 常见错误:注解事务不回滚

    最近项目在用springMVC+spring+myBatis框架,在配置事务的时候发现一个事务不能回滚的问题. 刚开始配置如下:springMVC.xml配置内容: spring.xml配置内容 从上 ...

  8. spring事务——try{...}catch{...}中事务不回滚的几种处理方式

    当希望在某个方法中添加事务时,我们常常在方法头上添加@Transactional注解 @ResponseBody @RequestMapping(value = "/payment" ...

  9. spring事务——try{...}catch{...}中事务不回滚的几种处理方式(转载)

    转载自   spring事务——try{...}catch{...}中事务不回滚的几种处理方式   当希望在某个方法中添加事务时,我们常常在方法头上添加@Transactional注解 @Respon ...

随机推荐

  1. java 流输出的一些问题

    一.java流的控制首先要先准备一个文件,例如:File f = new File(d:/lol.txt); 二.可以使用如下指令创建流,用于不同的用途 1.FileInputStream,FileO ...

  2. PHP - curl实现采集

    1.开启curl支持 由于php环境安装后默认是没有打开curl支持的,需修改php.ini文件,找到;extension=php_curl.dll,把前面的冒号去掉,重启服务即可: 2.使用curl ...

  3. JavaScript的this和作用域

    本文主要讨论一下JS的作用域和this关键字.作用域,就是你的方法或者变量可访问的区域,是他们执行的上下文.如果你见过这样的代码: function someFunc() { var _this = ...

  4. CompletableFuture CompletableFuture.supplyAsync 异常处理

    CompletableFuture 异常处理completeExceptionally可以把异常抛到主线程 /** * User: laizhenwei * Date: 2018-01-30 Time ...

  5. 关于使用srping @RequestParam 容易出错的地方

    大家都知道,在spring中的@RequestParam主要用户传递参数用的,具体的解释就是将请求参数去数据映射到功能处理方法的参数上.其中包括三个参数: value:参数名字,即入参的请求参数名字, ...

  6. linux nginx常见问题及优化,压力测试,tomcat服务器优化

    nginx常见问题 nginx优化全局配置优化[root@web2 nginx]# vim conf/nginx.confuser nobody;worker_processes 1;(与cpu核心数 ...

  7. Android HotFix动态加载框架介绍

    HotFix(Deprecated) https://github.com/dodola/HotFix 请关注 RocooFix 我重新写了一个RocooFix框架,解决了Nuwa因为Gradle1. ...

  8. RFM模型及R语言实现

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 一.基本概念 根据美国数据库营销研究所Arth ...

  9. Ubuntu 上 hi3531 交叉编译环境 arm-hisiv100nptl-linux 搭建过程

    安装SDK 1.Hi3531 SDK包位置     在"Hi3531_V100R001***/01.software/board"目录下,您可以看到一个 Hi3531_SDK_Vx ...

  10. 致IT同仁 — IT人士常犯的17个职场错误

    记得刚参加工作时(那是97年),中国的IT刚刚兴起,那时,作为一个IT人士是一件很光荣的事,而那时的我正在做电气和电子相关的工作.99年第一次跳槽,进入了IT行业做软件开发.至今,中国的IT已经走过了 ...