近日测试用例,发现这样一个现象:
在业务代码中,有如下两种情况,比如:
throw new RuntimeException("xxxxxxxxxxxx"); 事物回滚
throw new Exception("xxxxxxxxxxxx"); 事物没有回滚

自以为很了解事物,或许时间久远的缘故,没分析出来何故,遂查阅了下资料,写下了如下的内容,供参考:

1).Spring的AOP即声明式事务管理默认是针对unchecked exception回滚。也就是默认对RuntimeException()异常或是其子类进行事务回滚;checked异常,即Exception可try{}捕获的不会回滚,如果使用try-catch捕获抛出的unchecked异常后没有在catch块中采用页面硬编码的方式使用spring api对事务做显式的回滚,则事务不会回滚, “将异常捕获,并且在catch块中不对事务做显式提交=生吞掉异常” ,要想捕获非运行时异常则需要如下配置:

解决办法:
1.在针对事务的类中抛出RuntimeException异常,而不是抛出Exception。
2.在txAdive中增加rollback-for,里面写自己的exception,例如自己写的exception:
<tx:advice id="txAdvice" transaction-manager="transactionManager">
   <tx:attributes>
     <tx:method name="*" rollback-for="com.cn.untils.exception.XyzException"/>
   </tx:attributes>
 </tx:advice>
 
或者
定义不会滚的异常
<tx:advice id="txAdvice">
    <tx:attributes>
       <tx:method name="update*" no-rollback-for="IOException"/>
       <tx:method name="*"/>
    </tx:attributes>
 </tx:advice>
 
 
2).spring的事务边界是在调用业务方法之前开始的,业务方法执行完毕之后来执行commit or rollback(Spring默认取决于是否抛出runtime异常).
 如果抛出runtime exception 并在你的业务方法中没有catch到的话,事务会回滚。 
 一般不需要在业务方法中catch异常,如果非要catch,在做完你想做的工作后(比如关闭文件等)一定要抛出runtime exception,否则spring会将你的操作commit,这样就会产生脏数据.所以你的catch代码是画蛇添足。
 
如:
try {  
    //bisiness logic code  
} catch(Exception e) {  
    //handle the exception  
}

由此可以推知,在spring中如果某个业务方法被一个 整个包裹起来,则这个业务方法也就等于脱离了spring事务的管理,因为没有任何异常会从业务方法中抛出!全被捕获并吞掉,导致spring异常抛出触发事务回滚策略失效。
 不过,如果在catch代码块中采用页面硬编码的方式使用spring api对事务做显式的回滚,这样写也未尝不可。
 
 3).基于注解的事物:
 Transactional的异常控制,默认是Check Exception 不回滚,unCheck Exception回滚
 如果配置了rollbackFor 和 noRollbackFor 且两个都是用同样的异常,那么遇到该异常,还是回滚
 rollbackFor 和noRollbackFor 配置也许不会含盖所有异常,对于遗漏的按照Check Exception 不回滚,unCheck Exception回滚

Spring AOP声明式事务异常回滚的更多相关文章

  1. Spring AOP声明式事务异常回滚(转)

    转:http://hi.baidu.com/iduany/item/20f8f8ed24e1dec5bbf37df7 Spring AOP声明式事务异常回滚 近日测试用例,发现这样一个现象:在业务代码 ...

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

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

  3. spring aop 声明式事务管理

    一.声明式事务管理的概括 声明式事务(declarative transaction management)是Spring提供的对程序事务管理的方式之一. Spring的声明式事务顾名思义就是采用声明 ...

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

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

  5. spring mvc + mybatis + spring aop声明式事务管理没有作用

    在最近的一个项目中,采用springMVC.mybatis,发现一个很恼人的问题:事务管理不起作用!!网上查阅了大量的资料,尝试了各种解决办法,亦未能解决问题! spring版本:3.0.5 myba ...

  6. Spring aop 影响本地事务的回滚总结

    1  @Before   不会,因为还没执行到service的业务逻辑 2  @ After    默认情况下,报错会影响事务回滚., 当设置@Order属性并设置值优先级大小, 即使报错也不会回滚了 ...

  7. Spring之声明式事务

    在讲声明式事务之前,先回顾一下基本的编程式事务 编程式事务: //1.获取Connection对象 Connection conn = JDBCUtils.getConnection(); try { ...

  8. 【Spring】——声明式事务配置详解

    项目中用到了spring的事务: @Transactional(rollbackFor = Exception.class, transactionManager = "zebraTrans ...

  9. @Transactional、Spring的声明式事务

    传送门 一.Spring的声明式事务 需要在xml文件中配置 <!--配置事务管理器类--> <bean id="transactionManager" clas ...

随机推荐

  1. yum安装mysql后root用户的临时密码

    1.查看root用户临时随机密码 yum 安装mysql后,无法通过空密码登录数据库,如下: [root@ mysql]# mysql -u root -p Enter password: ERROR ...

  2. Jenkins自动打包配置

    当时也是花费了不少时间来配置Jenkins自动打包的问题,觉得还是需要记录一下. 1.安装Jenkins,这个很简单,不需要多说. 2.下载Git Plugin,Gradle Plugin,Andro ...

  3. 关于iOS开发的学习

    关于iOS开发的学习,打个比方就像把汽车分解:    最底层的原料有塑料,钢铁    再用这些底层的东西造出来发动机,座椅    最后再加上写螺丝,胶水等,把汽车就拼起来了 iOS基本都是英文的资料, ...

  4. windchill系统——一些功能查找

    1.创建产品 导航栏的浏览——>最近的产品——>全部查看——>新建产品——>填写“名称”.选择“模板”.一定的“说明”.“专用访问权限”一般选择“否”——>“确定”选项 ...

  5. C++中map的用法

    map的特性是,所有元素都会根据元素的减值自动被排序.map的所有元素都是pair,同时拥有实值(value)和键值(key).pair的第一个元素会被视为键值,第二个元素会被视为实值.map不允许两 ...

  6. linux service start|stop|restart

    用了这么些日子的linux/unix系统,也和别人一起合作开发了不少程序,发现高手都喜欢在命令行上操作,而且控制程序的运行偏好于使用脚本,加上参数如:start.restart.stop等. 后来自己 ...

  7. Pandas可视化

    基本绘图:绘图 Series和DataFrame上的这个功能只是使用matplotlib库的plot()方法的简单包装实现.参考以下示例代码 - import pandas as pd import ...

  8. scala学习手记16 – scala中的static

    前面两节学了scala的对象和伴生对象,这两个在使用的时候很有些java的静态成员的意思. scala中没有静态字段和静态方法.静态成员会破坏scala所支持的完整的面向对象模型.不过可以通过伴生对象 ...

  9. ZC_疑问

    1. 应该可以将所有的 jni需要的函数都放在一个 dll中(Windows下),然后 多个java项目就只要调用一个dll了. 可以测试一下 2.

  10. D3.js学习笔记(二)——使用绑定在DOM上的数据

    简单例子 在这个例子中,你将会使用D3.js来将数据绑定到DOM元素上.然后再使用D3.js利用绑定到DOM元素上的数据来更新网页. 在上一章中,我们以下面这个页面作为开始的: <!DOCTYP ...