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

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

第一、在当前方法的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. Statistics : Data Distribution

    1.Normal distribution In probability theory, the normal (or Gaussian or Gauss or Laplace–Gauss) dist ...

  2. 强化学习七 - Policy Gradient Methods

    一.前言 之前我们讨论的所有问题都是先学习action value,再根据action value 来选择action(无论是根据greedy policy选择使得action value 最大的ac ...

  3. python光标图片获取

    # -*- coding:utf-8 -*- import win32api import win32gui,win32ui import time while True : time.sleep(1 ...

  4. RocketMQ 整合 DLedger(多副本)即主从切换实现平滑升级的设计技巧

    目录 1.阅读源码之前的思考 2.从 Broker 启动流程看 DLedger 2.1 构建 DefaultMessageStore 2.2 增加节点状态变更事件监听器 2.3 调用 DefaultM ...

  5. CSS | 圣杯布局、双飞翼布局 | 自适应三栏布局

    圣杯布局和双飞翼布局是前端工程师需要日常掌握的重要布局方式.两者的功能相同,都是为了实现一个两侧宽度固定,中间宽度自适应的三栏布局 虽然两者的实现方法略有差异,不过都遵循了以下要点: 1.两侧宽度固定 ...

  6. 《Java基础知识》Java静态内部类、匿名内部类、成员式内部类和局部内部类

    内部类可以是静态(static)的,可以使用 public.protected 和 private 访问控制符,而外部类只能使用 public,或者默认. 成员式内部类 在外部类内部直接定义(不在方法 ...

  7. 自定义滚动条(Custom ScrollBar)

    时间如流水,只能流去不流回! 点赞再看,养成习惯,这是您给我创作的动力! 本文 Dotnet9 https://dotnet9.com 已收录,站长乐于分享dotnet相关技术,比如Winform.W ...

  8. 计算机等级考试真题1(JAVA)

    答案: 01-05 C D A A C   06-10 B/D    C C C B 11-15 A C A C A 16-20 C B     C    21-25 D D C D D 26-30 ...

  9. B站上传字幕问题解决

    博客:blog.shinelee.me | 博客园 | CSDN B站上传字幕时,如果srt文件中出现如下空行,则会报错,仅上传了空行前的部分 于是写了个python脚本,如下: import pys ...

  10. jquery获取表单中的数据

               <form>                 <input name="username" type="text"/&g ...