Spring-Java事物回滚失效处理
spring-Java事物回滚失效处理最近在做项目中,无意间发现有个类在抛事物回滚操作,数据也正常的插入到数据库当中了,于是仔细查看看一下具体原因。
一切还是要从Java的检查型异常和非检查型异常说起。
那么什么是检查型异常什么又是非检查型异常呢?
最简单的判断点有两个:
1.继承自RuntimeException或Error的是非检查型异常,而继承自Exception的则是检查型异常(当然,RuntimeException本身也是Exception的子类)。
2.对非检查型类异常可以不用捕获,而检查型异常则必须用try……catch语句块进行处理或者把异常交给上级方法处理,总之就是必须写代码处理它。
Java 的异常结构如下图。其中直接继承Exception的异常,必须捕获,属于检查型异常。
再回过来看我的代码:
1、方法名前面有
- @Transactional
2、Spring的配置文件applicationContext-XXX.xml当中也有Spring事物的相关配置
- <bean id="transactionManager"
- class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="dataSource" />
- <property name="rollbackOnCommitFailure" value="true"></property>
- </bean>
但是为什么在Service层方法调用的时候,try……catch抛Exception异常已经提交的事物却没有回滚?
查看相关spring的文档后发现,原来spring声明式事务管理默认对非检查型异常和运行时异常进行事务回滚,而对检查型异常则不进行回滚操作。
代码中try……catch抛出的Exception异常,属于检查型异常,Spring的框架默认是不会进行回滚的。
在编程中对非检查型类异常可以不用捕获,而检查型异常则必须用try语句块进行处理或者把异常交给上级方法处理总之就是必须写代码处理它。
所以必须在service捕获异常,然后再次手动 throw 一个非检查型异常,这样事务方才起效。例如:
- try{
- …………
- } catch (Exception e) {
- …………
- throw new BusinessException(e.getMessage());
- }
或者
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事物回滚失效处理的更多相关文章
- spring的事物回滚
//默认spring只能在捕获到runtimeException时才会回滚, throw new RuntimeException("出现runtime异常"); } catch ...
- Spring aop切面插入事物回滚
<!-- tx标签配置 事物--> <tx:advice id="txadvice" transaction-manager="transactionM ...
- Spring事务不回滚原因分析
Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离. 在我完成一个项目的时候,遇到了一个Spring事务不回滚的问题,通过aspectJ和@Transacti ...
- Spring事务管理——回滚(rollback-for)控制
探讨Spring事务控制中,异常触发事务回滚原理.文章进行了6种情况下的Spring事务是否回滚. 以下代码都是基于Spring与Mybatis整合,使用Spring声明式事务配置事务方法. 1.不捕 ...
- msql,触发器无事物回滚,插入之前满足条件再插入
很少写mysql的触发器和存储过程,由于需要需要做一个很小的判断,要用到触发器,要达到的效果就是,插入之前判断是否满足条件如果不满足就不插入 如果用sqlserver 或者orcale 就很简单,按s ...
- 复习课程jdbc:使用配置文件properties进行连接数据库,数据库存取图片,批处理,时间戳,事物回滚等等
使用配置文件properties进行连接数据库 首先创建一个file自定义文件名,但是后缀名必须改为.properties(不分大小写):如config.properties: 然后双击config. ...
- springboot事物回滚
要添加事物 必须在方法上添加 @Transactional 注解 如果需要事物回滚有两个条件 1.方法中有异常或者主动抛异常 2.主动去回滚 TransactionAspectSupport.curr ...
- peewee 事物 回滚
peewee 事物 回滚 #!/usr/bin/env python # coding=utf-8 from peewee import * db = MySQLDatabase(host='123. ...
- C#里面的事物回滚,解决同步数据插入时出现重复数据
什么是事物回滚: 举个栗子,你在你家的银行分行取钱,取完钱数据要同步,而且可能每个分行都有一个存储这些数据的数据库,分行的这些 存取的记录都需要实时同步,如果你取完500刚好断电了,好嘛,分行可能刚记 ...
随机推荐
- 完美解决 No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android
问题描述 好久之前的一个Android项目,最近需要重构一下 因为Android Studio的开发环境以及Gradle的版本等等都进行了一定的更新,于是导入Project以后,出现了报错: No t ...
- cygwin下安装软件
cygwin下安装软件cygwin工具安装新的软件和常见的命令windows8.1下安装Cygwin并通过apt-cyg安装软件包Cygwin利用apt-cyg安装gcc.g++.make和gdb 首 ...
- 数据库原理及应用-数据库管理系统 DBMS
2018-02-20 14:35:34 数据库管理系统(英语:database management system,缩写:DBMS) 是一种针对对象数据库,为管理数据库而设计的大型电脑软件管理系统.具 ...
- PHP libevent函数基本介绍
3.2 主要函数介绍 按照使用libevnet库顺序,看一下相关函数做什么操作. 3.2.1 event_init 调用event_base_new,初始化struct event_base对象 ...
- Hive 表结构操作
添加列 add columns alter table table_name add columns (id int comment '主键ID' ) ; 默认在表所有字段之后,分区字段之前. 替换 ...
- springboot拦截器注入service为空
一般都是因为除了在拦截器之外,还需要在拦截器的配置类中,注册拦截器时没有使用spring的bean,而是使用了new创建bean造成的. @Configuration public class Web ...
- 【51nod-1138】连续整数的和
本来想着用尺取的思想,不过会超时.利用等差数列S = na+n*n(n-1)/2,得a = (2*S-n*(n-1))/(2*n),然后遍历n,只要满足a是整数就可以,这样复杂度从O(S)变成了O(s ...
- lambda表达式 <二>
概念了解: 1.什么是匿名委托(匿名方法的简单介绍.为什么要用匿名方法) 2.匿名方法的[拉姆达表达式]方法定义 3.匿名方法的调用(匿名方法的参数传递.使用过程中需要注意什么) 什么是匿名方法? 匿 ...
- LeetCode OJ:N-Queens(N皇后问题)
Given an integer n, return all distinct solutions to the n-queens puzzle. Each solution contains a d ...
- windows 下git 的配置安装与使用
一.安装GIT(过于简单略过) 二.配置git 二(一).配置git的user name和email 打开 git bash,输入 $ git config --global user.name &q ...