今天客户提出一个新问题,出库一批商品,提示失败了,但是库存数量却减少了。看了一下代码一头雾水,我们的代码加了事物,且捕获异常。

经过调试代码发现就是两个原因导致的

第一、在当前方法的catch中处理了捕获的异常,没有向上抛出异常,事务不能回滚

分析:

1.在Java中异常的基类为Throwable,他有两个子类Exception与Errors,同时RuntimeException就是Exception的子类;

2.RuntimeException,即运行时异常,为非受检(UNCHECKED)异常;

3.Exception的其他子类异常,为非运行时异常,为受检异常(CHECKED)异常;

Spring事务回滚机制是这样的:当所拦截的方法有指定异常抛出,事务才会自动进行回滚!

①被拦截方法-—— 注解式:方法或者方法所在类被@Transactional注解;

②异常—— 该方法的执行过程必须出现异常,这样事务管理器才能被触发,并对此做出处理;

③指定异常—— 默认配置下,事务只会对Error与RuntimeException及其子类这些UNChecked异常,做出回滚。一般的Exception这些Checked异常不会发生回滚(如果一般Exception想回滚要做出配置);

Spring的声明式事务是基于AOP的
   spring aop  异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理(如果自己捕获就不能被声明式事务感知),这样aop代理才能捕获到方法的异常,才能进行回滚,默认情况下aop只捕获runtimeexception的异常,但可以通过 。
    
配置来捕获特定的异常并回滚  
  换句话说在service的方法中不使用try catch 或者在catch中最后加上throw new runtimeexcetpion(),这样程序异常时才能被aop捕获进而回滚
  解决方案: 
  方案1.方法中不做异常捕获,或者在catch语句中最后增加throw new RuntimeException()语句,以便让aop捕获异常再去回滚,并且在上层(webservice客户端,view层action)要继续捕获这个异常并处理
  方案2.在方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常

第二、在catch中异常抛出Exception,并不是RuntimeException,导致也没有回滚

解决方法:

① 抛出Exception,同时在事务声明中加上@Transactional(rollbackFor = Exception.class)

② 在catch添加语句

catch (Exception e) {
e.printStackTrace();
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//就是这一句了,加上之后如果异常后会回滚的
}

spring @Transaction事务回滚失败的更多相关文章

  1. spring管理事务回滚

    spring 事务回滚 1.遇到的问题 当我们一个方法里面有多个数据库保存操作的时候,中间的数据库操作发生的错误.伪代码如下: ? 1 2 3 4 5 6 7 public method() {    ...

  2. Spring @Transactional ——事务回滚

    工作原理运行配置@Transactional注解的测试类的时候,具体会发生如下步骤1)事务开始时,通过AOP机制,生成一个代理connection对象,并将其放入DataSource实例的某个与Dat ...

  3. alter table导致的mysql事务回滚失败

    今天做数据迁移, 发现事务有时候可以回滚, 有时候不可以回滚, 最后一点点调试发现中间有段修改表结构的语句, 最终导致回滚失败. 1.MySQL最常用的两个表类型: InnoDB和MyISAM.MyI ...

  4. spring的事务回滚

    @Transactional(rollbackFor = { Exception.class }) 需要把异常抛出到带有@Transactional(rollbackFor = { Exception ...

  5. 浅谈Spring中的事务回滚

        使用Spring管理事务过程中,碰到过一些坑,因此也稍微总结一下,方便后续查阅. 1.代码中事务控制的3种方式 编程式事务:就是直接在代码里手动开启事务,手动提交,手动回滚.优点就是可以灵活控 ...

  6. spring事务回滚问题

    刚刚接到一个上家公司同事的一个电话,问我为什么service方法事务不会滚了,日志打印了,调用webservice报错. 我让他把这个调用执行webservice的方法截图发给我,如下:   publ ...

  7. ssh事务回滚,纪念这几个月困扰已久的心酸

    以前的事务采用的是JTA,xml注入的方式.本人就着开发要优雅合理利用轮子的态度,一直不满意JTA式的申明和切入方式. spring的注解方式多优雅,可是万恶的直到项目快要上线时终于找到了注解式不能回 ...

  8. 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】

    一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...

  9. Spring transaction事务之roll back回滚

    转载自:http://blog.csdn.net/lovejavaydj/article/details/7635848 试验方法: 写一个单元测试,调用一个service层方法(发生对数据库进行写操 ...

随机推荐

  1. [TimLinux] CSS 实现加载中的动画

    内容来自对<CSS世界>学习代码的理解简化: <!DOCTYPE html> <html> <head> <style> div { pad ...

  2. leaflet 结合 geoserver 实现地图空间查询(附源码下载)

    前言 leaflet 入门开发系列环境知识点了解: leaflet api文档介绍,详细介绍 leaflet 每个类的函数以及属性等等 leaflet 在线例子 leaflet 插件,leaflet ...

  3. 2019CCPC秦皇岛 J MUV LUV EXTRA(KMP)

    MUV LUV EXTRA Time Limit: 2000/1500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)T ...

  4. CodeChef FAVNUM FavouriteNumbers(AC自动机+数位dp+二分答案)

    All submissions for this problem are available. Chef likes numbers and number theory, we all know th ...

  5. HDU-1595Find the longest of shortest(最短路径的最长路Dijkstra+记录路径)

    Marica is very angry with Mirko because he found a new girlfriend and she seeks revenge.Since she do ...

  6. ARTS-S sed指定行添加

    sed -i 's#^AAAA.*#&BBBB#g' a.txt 在以AAA开始的行懂添加BBBB

  7. 【Selenium】自动进入网页,出现弹窗被卡住

    问题现象: 使用命令:driver.get("http://127.0.0.1/zentao/user-login.html") 进入网页,出现如下弹窗,无法进入 解决方法: #d ...

  8. 理解Vue中的ref和$refs

    参考博客:https://www.cnblogs.com/xumqfaith/p/7743387.html

  9. 10分钟理解BFC原理

    10 分钟理解 BFC 原理 一.常见定位方案 在讲 BFC 之前,我们先来了解一下常见的定位方案,定位方案是控制元素的布局,有三种常见方案: 普通流 (normal flow) 在普通流中,元素按照 ...

  10. 开启html元素的编辑模式contenteditable="true"

    开启html元素的编辑模式contenteditable="true"