(转)spring异常抛出触发事务回滚策略
背景:在面试时候问到事务方法在调用过程中出现异常,是否会传递的问题,平时接触的比较少,有些懵逼。
spring异常抛出触发事务回滚策略
Spring、EJB的声明式事务默认情况下都是在抛出unchecked exception后才会触发事务的回滚
测试用业务逻辑方法:
/**
* 如果在spring事务配置中不为切入点(如这里的切入点可以定义成test*)配置事务在什么情况下回滚(格式:-引起回滚的异常类型)
* 则spring默认只会在service方法抛出unchecked exception才会触发回滚
*/
public class TestServiceImpl extends Service implements TestService { /**
* 测试spring异常触发事务回滚的service方法
*/
public void testAddPerson(String name) throws Exception {
TestPerson p = new TestPerson();
p.setName(name);
this.getHibernateGenericController().save(p); /*
* 制造RuntimeException
* 在spring默认的异常回滚策略下,该异常的抛出会触发事务的回滚,数据不会被插入
*/
throw new RuntimeException("抛出个运行时异常"); /**
* 同样是unchecked exception,spring默认的异常回滚策略下Error的抛出也会触发事务的回滚,数据不会被插入
*/
// throw new Error(); /**
* 即使是在spring默认的异常触发事务回滚策略(unchecked exception触发回滚)下,
* 如果使用try-catch捕获抛出的unchecked异常后没有在catch块中采用页面硬编码的方式使用spring api对事务做显式的回滚,则事务不会回滚,数据被插入
* “将异常捕获,并且在catch块中不对事务做显式提交=生吞掉异常”
*/
// try {
// throw new RuntimeException("这个抛出的运行时异常会被try-catch捕获");
// } catch(Exception e) {
// System.out.println("捕获到异常: " + e.getMessage());
// } /**
* 因为Exception类是个checked exception,所以这里抛出的异常不会触发事务的回滚,数据被插入
*/
// throw new Exception("a Exception instance"); /**
* 该BaseException继承自Exception,也为checked exception,抛出它后:
* spring默认的回滚策略下,事务未回滚, 数据被插入;
* 在TransactionProxyFactoryBean的transactionAttributes中配置
<prop key="test*">
... ...,-BaseException
</prop>
后,事务回滚,数据未被插入
*/
// throw new BaseException("一个BaseException");
} }
关于TransactionProxyFactoryBean的transactionAttributes中字符串的值(定义自TransactionAttributeEditor):
is a transaction attribute descriptors that parsed via TransactionAttributeEditor
见本博客:http://wuaner.iteye.com/admin/blogs/567792
单元测试代码:
public class TestSpringDefaultRollback extends TestCase {
private static ApplicationContext context = new ClassPathXmlApplicationContext("resource/xxx/applicationContext.xml");
public void testDefaultRollback() throws Exception{
TestService testServiceImpl = (TestService)context.getBean("testService");
testServiceImpl.testAddPerson("张三");
}
}
将异常捕获,并且在catch块中不对事务做显式提交(或其他应该做的操作如关闭资源等)=生吞掉异常
spring的事务边界是在调用业务方法之前开始的,业务方法执行完毕之后来执行commit or rollback(Spring默认取决于是否抛出runtime异常).
如果抛出runtime exception 并在你的业务方法中没有catch到的话,事务会回滚。
一般不需要在业务方法中catch异常,如果非要catch,在做完你想做的工作后(比如关闭文件等)一定要抛出runtime exception,否则spring会将你的操作commit,这样就会产生脏数据.所以你的catch代码是画蛇添足。
由此可以推知,在spring中如果某个业务方法被一个
try {
//bisiness logic code
} catch(Exception e) {
//handle the exception
}
整个包裹起来,则这个业务方法也就等于脱离了spring事务的管理,因为没有任何异常会从业务方法中抛出!全被捕获并吞掉,导致spring异常抛出触发事务回滚策略失效。
不过,如果在catch代码块中采用页面硬编码的方式使用spring api对事务做显式的回滚,这样写也未尝不可。
详解Java中的checked异常和unchecked异常
ps:讲解很清楚
再来看什么是checked异常,什么是unchecked的异常。其实,Java语言规范对这两个定义十分简单,
将派生于Error或者RuntimeException的异常称为unchecked异常,所有其他的异常成为checked异常。
如果出现了RuntimeException,就一定是程序员自身的问题。
这些异常发生时, java虚拟机一般会终止线程 .
NullPointerException、IndexOutOfBoundsException等, 这些异常是不检查的异常,
是在程序运行的时候可能会发生的, 所以程序可以捕捉, 也可以不捕捉. 这些错误一般是由程序的逻辑错误引起的, 程序应该从逻辑角度去尽量避免.
否则不能通过编译. 如IOException、SQLException等
(转)spring异常抛出触发事务回滚策略的更多相关文章
- Spring异常抛出触发事务回滚
Spring.EJB的声明式事务默认情况下都是在抛出unchecked exception后才会触发事务的回滚 /** * 如果在spring事务配置中不为切入点(如这里的切入点可以定义成test*) ...
- spring boot 使用 mybatis 开启事务回滚 的总结
1.前言 以前没有使用mybatis,可以关闭自动提交,然后做sql操作,对操作进行catch捕获异常, 如果没有异常则commit 提交 ,有异常则 rollback 回滚,新增的数据则删除 ,修改 ...
- Spring mvc注解方式使用事务回滚
项目名:1ma1ma jdbc.xml <bean id="dataSource" class="org.apache.commons.dbcp.BasicDat ...
- 采购订单写入sap失败后,抛出自定义异常,回滚数据库
@Transactional(rollbackFor = Exception.class) @Override public Map<String,Object> getOderInfo( ...
- spring @Transaction事务回滚失败
今天客户提出一个新问题,出库一批商品,提示失败了,但是库存数量却减少了.看了一下代码一头雾水,我们的代码加了事物,且捕获异常. 经过调试代码发现就是两个原因导致的 第一.在当前方法的catch中处理了 ...
- Spring 事务回滚机制详解
1:事务原理 1.2:aop/动态代理 类路径:org/springframework/aop/framework/CglibAopProxy.java ReflectiveMethodInvocat ...
- Java进阶知识24 Spring的事务管理(事务回滚)
1.事务控制概述 1.1.编程式事务控制 自己手动控制事务,就叫做编程式事务控制. Jdbc代码: connection.setAutoCommit(false); ...
- Spring事务回滚和异常类
1.异常的一些基本知识 异常的架构 异常的继承结构:Throwable为基类,Error和Exception继承Throwable.Error和RuntimeException及其子类成为未检查异常( ...
- Spring boot 前后台分离项目 怎么处理spring security 抛出的异常
最近在开发一个项目 前后台分离的 使用 spring boot + spring security + jwt 实现用户登录权限控制等操作.但是 在用户登录的时候,怎么处理spring securi ...
随机推荐
- EF时,数据库字段和实体类不一致问题
场景:由于一些原因,实体中属性比数据库中字段多了一个startPage属性.PS:controllers中用实体类去接收参数,但是传入的参数比数据库中实体表多了一个字段, 这种情况下,应该建一个vie ...
- WebGL或OpenGL关于模型视图投影变换的设置技巧
目录 1. 具体实例 2. 解决方案 1) Cube.html 2) Cube.js 3) 运行结果 3. 详细讲解 1) 模型变换 2) 视图变换 3) 投影变换 4) 模型视图投影矩阵 4. 存在 ...
- 使用 MapTiler 进行地图切片
在GIS开发中接触比较多的就是切图与发布,通常大家使用的是GlobalMapper.ArcGIS.GDAL等. 一般在使用Leaflet.js或其他框架开发时,使用的是TMS切片格式,大佬们基本用GD ...
- android常犯错误记录(三)
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionVie ...
- IOS跟ANDROID的区别
大家总是会纠结哪个手机系统会更加适合自己,那就由小编我简要介绍一下IOS和安卓的区别吧! 运行机制:安卓是虚拟机运行机制,IOS是沙盒运行机制.这里再说明一下这两者的主要不同之处.安卓系统中应用程序的 ...
- 【集合框架】JDK1.8源码分析之ArrayList详解(一)
[集合框架]JDK1.8源码分析之ArrayList详解(一) 一. 从ArrayList字表面推测 ArrayList类的命名是由Array和List单词组合而成,Array的中文意思是数组,Lis ...
- Ubuntu 16.04 屏幕亮度无法调节怎么办
安装好ubuntu 16.04之后,发现屏幕超亮,找不到调节按钮,这应该是系统的一个漏洞, 不过可以安装工具来操作,从而解决亮度调节问题,下面是安装 Brightness Controller 的方 ...
- .NET core2.0 发布至IIS中
.NET CORE和asp.net 发布时不太一样,ASP.NET Core不再是由IIS工作进程(w3wp.exe)托管,而是使用自托管Web服务器(Kestrel)运行,IIS则是作为反向代理的角 ...
- 闲谈2-sat问题
问题简介 在计算机科学中,布尔可满足性问题(有时称为命题可满足性问题,缩写为SATISFIABILITY或SAT)是确定是否存在满足给定布尔公式的解释的问题.换句话说,它询问给定布尔公式的变量是否可以 ...
- CodeBlocks卸载后重装 编译c文件提示错误信息“No such file or directory”
编译最简单的helloworld程序,提示第一行#include<stdio.h> 找不到头文件. 解决方法: 再次卸载CodeBlocks后,将之前的配置文件删除. 路径:C:\User ...