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刚好断电了,好嘛,分行可能刚记 ...
随机推荐
- 谈谈favicon和他带来的问题
favicon.ico介绍 favicon.ico是个什么东西呢,也许见得太多都习以为常了(我就是这样,直到写这篇文章之前才知道),看看维基百科的解释: Favicon是favorites icon的 ...
- [转载]堆排序(HeapSort) Java实现
堆排序的思想是利用数据结构--堆.具体的实现细节: 1. 构建一个最大堆.对于给定的包含有n个元素的数组A[n],构建一个最大堆(最大堆的特性是,某个节点的值最多和其父节点的值一样大.这样,堆中的最大 ...
- php 之 数据访问 增删改查
一.建立主页面: <title>主页面</title> </head> <body> <h1>主页面</h1> <tabl ...
- 『安全工具』目录扫描 DirBuster AND 御剑
要想熟悉目标网站的体系架构,知道网站有哪些目录是必不可少的 向AWVS,Burp类大型扫描工具也可以进行目录扫描,不过个人感觉远没有专业扫描工具来的简单,实在 0x 01 DirBuster 简介:D ...
- css3学习01
1.圆角边框(div的一个属性:border-radius) <!DOCTYPE html> <html> <head> <style> div { t ...
- python字典dict的成对运算
dict = {'age': 18, 'name': 'jin', 'sex': 'male', }# for k,v in dict.items():# print(k,v)# v1 = dict[ ...
- 基于 Promise 的 HTTP 请求客户端 axios
基于 Promise 的 HTTP 请求客户端,可同时在浏览器和 node.js 中使用 功能特性 在浏览器中发送 XMLHttpRequests 请求 在 node.js 中发送 http请求 支持 ...
- AngularJS 用 $http.jsonp 跨域SyntaxError问题
必须添加参数:callback=JSON_CALLBACK , 才能进success方法,如下: $http.jsonp("https://request.address.json?call ...
- Composer 添加 Laravel-china 的国内源
不知道由于什么原因,原来的 Composer 的国内镜像 https://pkg.phpcomposer.com/ 不能正常使用,经常连不上. 找了半天,发现还有一个 laravel-china 的国 ...
- python3出现转码问题的总结
对于此(类)问题: (1)出现UnicodeEncodeError –> 说明是Unicode编码时候的问题: (2) ‘gbk’ codec can’t encode character –& ...