Spring Transaction属性之Propagation
spring Transaction中有一个很重要的属性:Propagation。主要用来配置当前需要执行的方法,与当前是否有transaction之间的关系。
我晓得有点儿抽象,这也是为什么我想要写这篇博客的原因。看了后面的例子,大家应该就明白了。
一、Propagation取值:
REQUIRED(默认值):在有transaction状态下执行;如当前没有transaction,则创建新的transaction;
SUPPORTS:如当前有transaction,则在transaction状态下执行;如果当前没有transaction,在无transaction状态下执行;
MANDATORY:必须在有transaction状态下执行,如果当前没有transaction,则抛出异常IllegalTransactionStateException;
REQUIRES_NEW:创建新的transaction并执行;如果当前已有transaction,则将当前transaction挂起;
NOT_SUPPORTED:在无transaction状态下执行;如果当前已有transaction,则将当前transaction挂起;
NEVER:在无transaction状态下执行;如果当前已有transaction,则抛出异常IllegalTransactionStateException。
二、REQUIRED与REQUIRED_NEW
上面描述的6种propagation属性配置中,最难以理解,并且容易在transaction设计时出现问题的是REQUIRED和REQURED_NEW这两者的区别。当程序在某些情况下抛出异常时,如果对于这两者不够了解,就可能很难发现而且解决问题。
下面我们给出三个场景进行分析:
场景一:
ServiceA.Java:
public class ServiceA {
@Transactional
public void callB() {
serviceB.doSomething();
}
}
ServiceB.java
public class ServiceB {
@Transactional
public void doSomething() {
throw new RuntimeException("B throw exception");
}
}
这种情况下,我们只需要在调用ServiceA.callB时捕获ServiceB中抛出的运行时异常,则transaction就会正常的rollback。
场景二
在保持场景一中ServiceB不变,在ServiceA中调用ServiceB的doSomething时去捕获这个异常,如下:
public class ServiceA {
@Transactional
public void callB() {
try {
serviceB.doSomething();
} catch (RuntimeException e) {
System.err.println(e.getMessage());
}
}
}
这个时候,我们再调用ServiceA的callB。程序会抛出org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only这样一个异常信息。原因是什么呢?
因为在ServiceA和ServiceB中的@Transactional propagation都采用的默认值:REQUREID。根据我们前面讲过的REQUIRED特性,当ServiceA调用ServiceB的时候,他们是处于同一个transaction中。如下图所示:
当ServiceB中抛出了一个异常以后,ServiceB会把当前的transaction标记为需要rollback。但是ServiceA中捕获了这个异常,并进行了处理,认为当前transaction应该正常commit。此时就出现了前后不一致,也就是因为这样,抛出了前面的UnexpectedRollbackException。
场景三
在保持场景二中ServiceA不变,修改ServiceB中方法的propagation配置为REQUIRES_NEW,如下:
public class ServiceB {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void doSomething() {
throw new RuntimeException("B throw exception");
}
}
此时,程序可以正常的退出了,也没有抛出UnexpectedRollbackException。原因是因为当ServiceA调用ServiceB时,serviceB的doSomething是在一个新的transaction中执行的。如下图所示:
所以,当doSomething抛出异常以后,仅仅是把新创建的transaction rollback了,而不会影响到ServiceA的transaction。ServiceA就可以正常的进行commit。
当然这里把ServiceA和ServiceB放在两个独立的transaction是否成立,还需要再多多考虑你的业务需求。
Transaction不是一个新东西了,那对于transaction的使用会不会有一些模式?一些经验之谈呢?答案肯定是有的,以后博客再说。
Spring Transaction属性之Propagation的更多相关文章
- spring Transaction Propagation 事务传播
spring Transaction中有一个很重要的属性:Propagation.主要用来配置当前需要执行的方法,与当前是否有transaction之间的关系. 我晓得有点儿抽象,这也是为什么我想要写 ...
- spring Existing transaction found for transaction marked with propagation 'never' 解决
先在申明事务中配置了所有的事务 <!--配置事物传播策略,以及隔离级别--> <tx:advice id="txAdvice" transaction-manag ...
- spring transaction 初识
spring 事务初识 1.spring事务的主要接口,首先盗图一张,展示出spring 事务的相关接口.Spring并不直接管理事务,而是提供了多种事务管理器,他们将事务管理的职责委托给Hibern ...
- Spring 事务 属性 详细
学习东西要知行合一,如果只是知道理论而没实践过,那么掌握的也不会特别扎实,估计过几天就会忘记,接下来我们一起实践来学习Spring事务的传播属性. 传播属性 传播属性定义的是当一个事务方法碰到另一个事 ...
- Spring Transaction 使用入门
一.开篇陈述 1.1 写文缘由 最近在系统学习spring框架IoC.AOP.Transaction相关的知识点,准备写三篇随笔记录学习过程中的感悟.这是第一篇,记录spring Transactio ...
- Spring学习记录1--@Transactional Propagation
起因 学习Spring的时候就知道aop有一个应用是声明式注解..反正往Service上一丢@Transactional就完事了..不用自己去开启hibernate的session,很简单. 但是@T ...
- spring Transaction Management --官方
原文链接:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html 12. ...
- Spring Boot属性文件配置文档(全部)
This sample file is meant as a guide only. Do not copy/paste the entire content into your applicatio ...
- springboot成神之——spring boot,spring jdbc和spring transaction的使用
本文介绍spring boot,spring jdbc和spring transaction的使用 项目结构 依赖 application model层 mapper层 dao层 exception层 ...
随机推荐
- 解决Myeclipse 编辑jsp页面卡
解决Myeclipse 编辑jsp页面卡 编辑一个jsp页面时,如果每输入一下,CPU都100%一下,和大家分项一下. 问题: 当你编辑一个jsp页面时,如果每输入一下,CPU都100%一下,3, ...
- poj 3903 Stock Exchange(最长上升子序列,模版题)
题目 #include<stdio.h> //最长上升子序列 nlogn //入口参数:数组名+数组长度,类型不限,结构体类型可以通过重载运算符实现 //数组下标从1号开始. int bs ...
- DOS永久设置系统环境变量-WMIC
wmic Windows Management Instrumentation Command-line(Windows管理规范命令行) WMIC扩展WMI(Windows Management In ...
- POJ 1947 Rebuilding Roads(树形DP)
题目链接 题意 : 给你一棵树,问你至少断掉几条边能够得到有p个点的子树. 思路 : dp[i][j]代表的是以i为根的子树有j个节点.dp[u][i] = dp[u][j]+dp[son][i-j] ...
- 浅谈mysql中varchar(m)与char(n)的区别与联系
mysql建表长度的限制 在mysql建表时,出现以下报错信息: 错误一:行大小过大,所使用的表这种类型的最大的行大小,不算BLOB类型,是65535.(这是我翻译的) 原因是MySQL在建表的 ...
- spring PropertyPlaceholderConfigurer 找不到配置文件原因
1: spring 版本问题 参见: http://www.cnblogs.com/alex-blog/archive/2012/12/25/2832357.html 2: bean id 同名 ...
- session原理总结
session原理总结 session多服务器共享的方案梳理 session原理 session的工作原理 客户端禁用cookie时session解决方案[转]
- 【web性能】让css更简洁、高效
用了这么多年的CSS,现在才明白CSS的真正匹配原理,不知道你是否也跟我一样? 看1个简单的CSS: DIV#divBox p span.red{color:red;},按习惯我们对这个CSS 的 ...
- 预编译头文件 StdAfx.h
预编译头文件: 最常见的使用场景就是 StdAfx.h 文件,在这个文件中包含常用的头文件,比如windows.h,cstdio,string,别的 .cpp 文件去包含 StdAfx.h 头文件.编 ...
- Java:网络编程之UDP的使用
java.net 类 DatagramSocket 此类表示用来发送和接收数据报包的套接字,数据报套接字是包投递服务的发送或接收点. java.net 类 DatagramPacket 此类表示数 ...