spring-Java事物回滚失效处理最近在做项目中,无意间发现有个类在抛事物回滚操作,数据也正常的插入到数据库当中了,于是仔细查看看一下具体原因。

一切还是要从Java的检查型异常和非检查型异常说起。

那么什么是检查型异常什么又是非检查型异常呢?

 最简单的判断点有两个:

    1.继承自RuntimeException或Error的是非检查型异常,而继承自Exception的则是检查型异常(当然,RuntimeException本身也是Exception的子类)。

    2.对非检查型类异常可以不用捕获,而检查型异常则必须用try……catch语句块进行处理或者把异常交给上级方法处理,总之就是必须写代码处理它。

Java 的异常结构如下图。其中直接继承Exception的异常,必须捕获,属于检查型异常。

再回过来看我的代码:

1、方法名前面有

  1. @Transactional

2、Spring的配置文件applicationContext-XXX.xml当中也有Spring事物的相关配置

  1. <bean id="transactionManager"
  2. class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  3. <property name="dataSource" ref="dataSource" />
  4. <property name="rollbackOnCommitFailure" value="true"></property>
  5. </bean>

但是为什么在Service层方法调用的时候,try……catch抛Exception异常已经提交的事物却没有回滚?

查看相关spring的文档后发现,原来spring声明式事务管理默认对非检查型异常和运行时异常进行事务回滚,而对检查型异常则不进行回滚操作。

代码中try……catch抛出的Exception异常,属于检查型异常,Spring的框架默认是不会进行回滚的。

在编程中对非检查型类异常可以不用捕获,而检查型异常则必须用try语句块进行处理或者把异常交给上级方法处理总之就是必须写代码处理它。

所以必须在service捕获异常,然后再次手动 throw 一个非检查型异常,这样事务方才起效。例如:

  1. try{
  2. …………
  3. } catch (Exception e) {
  4. …………
  5. throw new BusinessException(e.getMessage());
  6. }

或者

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

当然我们还有更简便的方法来解决这个问题,那就是通过注解参数改变默认的回滚方式 。

在@Transaction注解中定义了noRollbackFor和RollbackFor来指定某种异常是否回滚。

使用例:

@Transaction(noRollbackFor=RuntimeException.class)

@Transaction(RollbackFor=Exception.class)

所以上述的问题可以直接将@Transaction添加回滚参数@Transaction(RollbackFor=Exception.class) ,这样就改变了默认的事务处理方式。

启示 :

这就要求我们在自定义异常的时候,让自定义的异常继承自RuntimeException,这样抛出的时候才会被Spring默认的事务处理准确处理。

Spring-Java事物回滚失效处理的更多相关文章

  1. spring的事物回滚

    //默认spring只能在捕获到runtimeException时才会回滚, throw new RuntimeException("出现runtime异常"); } catch ...

  2. Spring aop切面插入事物回滚

    <!-- tx标签配置 事物--> <tx:advice id="txadvice" transaction-manager="transactionM ...

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

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

  4. Spring事务管理——回滚(rollback-for)控制

    探讨Spring事务控制中,异常触发事务回滚原理.文章进行了6种情况下的Spring事务是否回滚. 以下代码都是基于Spring与Mybatis整合,使用Spring声明式事务配置事务方法. 1.不捕 ...

  5. msql,触发器无事物回滚,插入之前满足条件再插入

    很少写mysql的触发器和存储过程,由于需要需要做一个很小的判断,要用到触发器,要达到的效果就是,插入之前判断是否满足条件如果不满足就不插入 如果用sqlserver 或者orcale 就很简单,按s ...

  6. 复习课程jdbc:使用配置文件properties进行连接数据库,数据库存取图片,批处理,时间戳,事物回滚等等

    使用配置文件properties进行连接数据库 首先创建一个file自定义文件名,但是后缀名必须改为.properties(不分大小写):如config.properties: 然后双击config. ...

  7. springboot事物回滚

    要添加事物 必须在方法上添加 @Transactional 注解 如果需要事物回滚有两个条件 1.方法中有异常或者主动抛异常 2.主动去回滚 TransactionAspectSupport.curr ...

  8. peewee 事物 回滚

    peewee 事物 回滚 #!/usr/bin/env python # coding=utf-8 from peewee import * db = MySQLDatabase(host='123. ...

  9. C#里面的事物回滚,解决同步数据插入时出现重复数据

    什么是事物回滚: 举个栗子,你在你家的银行分行取钱,取完钱数据要同步,而且可能每个分行都有一个存储这些数据的数据库,分行的这些 存取的记录都需要实时同步,如果你取完500刚好断电了,好嘛,分行可能刚记 ...

随机推荐

  1. Spring的注解配置与XML配置之间的比较

    注释配置相对于 XML 配置具有很多的优势: 它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作. 如:使用 JPA 注释配置 ORM 映射时,我们就不需要指定 PO ...

  2. [nodejs]npm国内npm安装nodejs modules终极解决方案

    此方案用于设置代理和修改镜像地址都不能解决问题使用 1.npm root 确认node模块的根文件夹,全局要加-g. osx同样是此命令,先清除缓存. npm cache clean C:\Users ...

  3. centos7 配置 NFS mount挂载服务器

    1. NFS服务端 安装NFS服务 yum install nfs_utils yum install rpcbind (系统默认已经有了,可查看下) 配置共享文件夹 1.    创建文件夹: mkd ...

  4. 转载:【Oracle 集群】RAC知识图文详细教程(七)--Oracle 11G RAC集群安装

    文章导航 集群概念介绍(一) ORACLE集群概念和原理(二) RAC 工作原理和相关组件(三) 缓存融合技术(四) RAC 特殊问题和实战经验(五) ORACLE 11 G版本2 RAC在LINUX ...

  5. hdu3718

    题解: 见图 按照每一个位置上有相同加一 然后km 代码: #include<cstdio> #include<cmath> #include<cstring> # ...

  6. 模式窗体中调用父页面js与非模式化调用非父页面的js方法

    最近项目中使用模式窗体,遇到以下问题记录一下: 模式窗体:你必须关闭该窗体,才能操作其它窗体:比如说,必须按确定或取消,或者按关闭. 非模式窗体:不必关闭该窗体,就可转换到其它窗体上进行操作. 一:非 ...

  7. APUE学习笔记——6.10 时间与时间例程 time_t

           Unix提供的最基本的时间服务室日历时间(纪元时间),也就是计算1970年1月1日0时0分0秒到当前的秒数.该秒数用time_t表示. typedef long time_t; /* 时 ...

  8. IR Cut Filter

    IR cut filter,即红外截止滤光片,它放在于LENS与Sensor之间.因人眼与CMOS Sensor对各波长的响应不同,人眼看不到红外光但sensor会感应,因此需要IR cut filt ...

  9. Shell 命令行 从日志文件中根据将符合内容的日志输出到另一个文件

    Shell 命令行 从日志文件中根据将符合内容的日志输出到另一个文件 前面我写了一篇博文Shell 从日志文件中选择时间段内的日志输出到另一个文件,利用循环实现了我想要实现的内容. 但是用这个脚本的同 ...

  10. VS2010对c++11的支持情况验证

    目前仅仅测试工作中 使用的比较多的: 智能指针 shared_ptr #include <memory> std::shared_ptr<A> a(new A); ----支持 ...