https://www.cnblogs.com/cnmenglang/p/6410848.html

先了解事务的7种传播属性:

PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED -- 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
前六个策略类似于EJB CMT,第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。
它要求事务管理器或者使用JDBC 3.0 Savepoint API提供嵌套事务行为(如Spring的DataSourceTransactionManager)

问题产生场景:

 1.在 DemoServiceA.java中有方法 demoMethodA().其中嵌套DemoServiceB.java中demoMethodB()。当demoMethodA事务发生rollback时, demoMethodB 事务也可以rollback或是commit。

如图:

public class DemoServiceA {

    public void demoMethodA() {

        demoServiceB.demoMethodB();//Insert对象B 操作
} }

常见解决方案: 

public class DemoServiceA {

    /**
* 新建事务
* 事务属性配置为 PROPAGATION_REQUIRED
*/
@Transactional(propagation=Propagation.REQUIRED)
public void demoMethodA() {
//操作... /**
* 1.事务属性配置为 PROPAGATION_REQUIRES_NEW ;
* A. DemoServiceA 事务commit与rollback,与 DemoServiceB无任何关系,DemoServiceB 不属于事务 DemoServiceA的子事务。
* PROPAGATION_REQUIRES_NEW 启动一个新的, 不依赖于环境的 "内部" 事务. 这个事务将被完全 commited
* 或 rolled back 而不依赖于外部事务, 它拥有自己的隔离范围, 自己的锁, 当内部事务开始执行时,
* 外部事务将被挂起, 内务事务结束时, 外部事务将继续执行.
* B. 可以起到分支执行的效果。service方法虽然嵌套但是事务之间状态相互无影响
*
*
*
* 2.事务属性配置为 PROPAGATION_NESTED;
* PROPAGATION_NESTED 开始一个 "嵌套的" 事务, 它是已经存在事务的一个真正的子事务.
* 潜套事务开始执行时, 它将取得一个 savepoint. 如果这个嵌套事务失败,
* 我们将回滚到此 savepoint. 潜套事务是外部事务的一部分, 只有外部事务结束后它才会被提交.
*
*/
demoServiceB.demoMethodB();//Insert对象B 操作
//操作... }
}

下面详细介绍7种事务传播属性在示例中的作用:

1: REQUIRED

加入当前正要执行的事务不在另外一个事务里,那么就起一个新的事务

比如说,DemoServiceB.demoMethodB的事务级别定义为REQUIRED, 那么由于执行DemoServiceA.demoMethodA的时候,

DemoServiceA.demoMethodA已经起了事务,这时调用DemoServiceB.demoMethodB,DemoServiceB.demoMethodB看到自己已经运行在DemoServiceA.demoMethodA

的事务内部,就不再起新的事务。而假如DemoServiceA.demoMethodA运行的时候发现自己没有在事务中,他就会为自己分配一个事务。

这样,在DemoServiceA.demoMethodA或者在DemoServiceB.demoMethodB内的任何地方出现异常,事务都会被回滚。即使DemoServiceB.demoMethodB的事务已经被

提交,但是DemoServiceA.demoMethodA在接下来fail要回滚,DemoServiceB.demoMethodB也要回滚

2: SUPPORTS

如果当前在事务中,即以事务的形式运行,如果当前不再一个事务中,那么就以非事务的形式运行

3: MANDATORY

必须在一个事务中运行。也就是说,他只能被一个父事务调用。否则,他就要抛出异常

4: REQUIRES_NEW

这个就比较绕口了。 比如我们设计DemoServiceA.demoMethodA的事务级别为REQUIRED,DemoServiceB.demoMethodB的事务级别为REQUIRES_NEW,

那么当执行到DemoServiceB.demoMethodB的时候,DemoServiceA.demoMethodA所在的事务就会挂起,DemoServiceB.demoMethodB会起一个新的事务,等待DemoServiceB.demoMethodB的事务完成以后,

他才继续执行。他与REQUIRED 的事务区别在于事务的回滚程度了。因为DemoServiceB.demoMethodB是新起一个事务,那么就是存在

两个不同的事务。如果DemoServiceB.demoMethodB已经提交,那么DemoServiceA.demoMethodA失败回滚,DemoServiceB.demoMethodB是不会回滚的。如果DemoServiceB.demoMethodB失败回滚,

如果他抛出的异常被DemoServiceA.demoMethodA捕获,DemoServiceA.demoMethodA事务仍然可能提交。

5: NOT_SUPPORTED

当前不支持事务。比如DemoServiceA.demoMethodA的事务级别是REQUIRED ,而DemoServiceB.demoMethodB的事务级别是NOT_SUPPORTED ,

那么当执行到DemoServiceB.demoMethodB时,DemoServiceA.demoMethodA的事务挂起,而他以非事务的状态运行完,再继续DemoServiceA.demoMethodA的事务。

6: NEVER

不能在事务中运行。假设DemoServiceA.demoMethodA的事务级别是REQUIRED, 而DemoServiceB.demoMethodB的事务级别是NEVER ,

那么DemoServiceB.demoMethodB就要抛出异常了。

7: NESTED

理解Nested的关键是savepoint。他与REQUIRES_NEW的区别是,REQUIRES_NEW另起一个事务,将会与他的父事务相互独立,

而Nested的事务和他的父事务是相依的,他的提交是要等和他的父事务一块提交的。也就是说,如果父事务最后回滚,他也要回滚的。

spring事务[转]的更多相关文章

  1. spring事务概念理解

    1.数据并发问题 脏读 A事务读取B事务尚未提交的更新数据,并在此数据的基础上操作.如果B事务回滚,则A事务读取的数据就是错误的.即读取了脏数据或者错误数据. 不可重复组 A事务先后读取了B事务提交[ ...

  2. 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】

    一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...

  3. Spring事务

    1.@Transactional 只能被应用到public方法上, 对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能.@Transactional 的 ...

  4. spring事务管理器设计思想(二)

    上文见<spring事务管理器设计思想(一)> 对于第二个问题,涉及到事务的传播级别,定义如下: PROPAGATION_REQUIRED-- 如果当前没有事务,就新建一个事务.这是最常见 ...

  5. spring事务管理器设计思想(一)

    在最近做的一个项目里面,涉及到多数据源的操作,比较特殊的是,这多个数据库的表结构完全相同,由于我们使用的ibatis框架作为持久化层,为了防止每一个数据源都配置一套规则,所以重新实现了数据源,根据线程 ...

  6. Spring事务管理的三种方式

    一 .第一种:全注解声明式事务 Xml代码 复制代码 收藏代码 .<?xml version="1.0" encoding="UTF-8"?> .& ...

  7. spring 事务传播特性 和隔离级别

    事务的几种传播特性1. PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务.如果没有事务则开启2. PROPAGATION_SUPPORTS: 如果存在一个事务,支持当前事务 ...

  8. Spring事务管理

    Spring是SSH中的管理员,负责管理其它框架,协调各个部分的工作.今天一起学习一下Spring的事务管理.Spring的事务管理分为声明式跟编程式.声明式就是在Spring的配置文件中进行相关配置 ...

  9. Spring事务传播属性

    Spring 对事务控制的支持统一在 TransactionDefinition 类中描述,该类有以下几个重要的接口方法: int getPropagationBehavior():事务的传播行为 i ...

  10. Spring事务属性的介绍

    Spring声明式事务让我们从复杂的事务处理中得到解脱.使得我们再也无需要去处理获得连接.关闭连接.事务提交和回滚等这些操作.再也无需要我们在与事务相关的方法中处理大量的try-catch-final ...

随机推荐

  1. vue中的$route和$router的区别

    1. $route是一个对象 可以获取当前页面的路由的路径query.params.meta等参数: 2.$router是VueRouter的一个实例对象 在options中可以获取路由的routes ...

  2. yii2下载

    我发现yii2下载贼困难,不过折腾了很久终于搞下来了. 一,设置镜像 安装composer ,   下载 composer.phar 添加中国镜像   composer config -g repo. ...

  3. 【EMV L2】Select PSE应用选择相关的卡片数据格式

    The data field of the response message contains the FCI specific to the selected PSE, DDF, or ADF. 一 ...

  4. Chrome如何访问外网

    分享一下谷歌Chrome浏览器如何访问外网(FQ) 1.请确保你已经安装谷歌浏览器,同时能上网 2. 访问外网需要下载谷歌浏览器插件,网盘链接 https://pan.baidu.com/s/1R-b ...

  5. DEV gridview根据单元格值改变其他单元格格式

    string style = ""; private void gridView1_RowCellStyle(object sender, DevExpress.XtraGrid. ...

  6. js ·节点的知识点

    1. DOM document object model (1) 节点树状图 Document>documentElement>body>tagname 2. 我们常用的节点类型 元 ...

  7. 使用数据泵expdp、impdp备份和还原oracle数据库

    前面我已经整理过EXP 和 IMP备份和还原Oracle数据库的方法 今天我们只讲使用数据泵 expdp 和impdp的方法,有的同学会问他们有什么差别呢? EXP和IMP是客户端工具程序,它们既可以 ...

  8. About cookie

    1.cookie 是一种发送到客户浏览器的文本串句柄,并保存在客户机硬盘上,可以用来在某个WEB站点会话间持久的保持数据. 2.session其实指的就是访问者从到达某个特定主页到离开为止的那段时间. ...

  9. xc笔记

    2019-03-20正式开始准备 --言语理解与表达------------------------------------------------------- 分为 1.逻辑填空   2.片段阅读 ...

  10. 使用 AppScan 进行扫描

    针对大型网站的扫描,我们按照戴明环 PDCA 的方法论来进行规划和讨论,建议 AppScan 使用步骤:计划(Plan).执行(Do).检查(check).分析(Analysis and Action ...