先了解事务的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种事务传播属性在示例中的作用:

: 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也要回滚

: SUPPORTS

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

: MANDATORY

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

: 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事务仍然可能提交。

: NOT_SUPPORTED

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

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

: NEVER

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

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

: NESTED

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

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

关于Spring 事务管理传播属性的配置及作用-嵌套事务的更多相关文章

  1. Spring事务管理-传播行为-隔离级别

    事务是逻辑上的一组操作,这组操作要么全部成功,要么全部失败. 事务的特性:ACID 原子性:事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生 一致性:事务前后数据的完整性约束保持一致 ...

  2. Spring事务的传播属性

    前言 Spring在TransactionDefinition接口中规定了7种类型的事务传播行为.事务传播行为是Spring框架独有的事务增强特性,他不属于的事务实际提供方数据库行为.这是Spring ...

  3. spring事务管理实现原理-源码-传播属性

    转载请标识 https://me.csdn.net/wanghaitao4j https://blog.csdn.net/wanghaitao4j/article/details/83625260 本 ...

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

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

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

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

  6. spring事务管理——编程式事务、声明式事务

    本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本教程假定您已经掌握了 ...

  7. Spring事务管理(编码式、配置文件方式、注解方式)

    1.事务(https://www.cnblogs.com/zhai1997/p/11710082.html) (1)事务的特性:acdi (2)事务的并发问题:丢失修改,脏读,不可重复读 (3)事务的 ...

  8. Spring事务管理——回滚(rollback-for)控制

    探讨Spring事务控制中,异常触发事务回滚原理.文章进行了6种情况下的Spring事务是否回滚. 以下代码都是基于Spring与Mybatis整合,使用Spring声明式事务配置事务方法. 1.不捕 ...

  9. Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别

    转: http://blog.csdn.net/it_man/article/details/5074371 Spring事务配置的五种方式 前段时间对Spring的事务配置做了比较深入的研究,在此之 ...

随机推荐

  1. UIView 添加闪烁的渐变光

    CGRect gradientRect=CGRectMake(- imageView3.bounds.size.width*, * imageView3.bounds.size.width, imag ...

  2. php 中间件

    PHP ::双冒号,意为静态成员的访问形式. 中间件$request 速查表:

  3. java常见编码

    摘自:http://www.cnblogs.com/yaya-yaya/p/5768616.html 红色 主要点    灰色 内容      绿色  知识点    橘色 补充内容 几种常见的编码格式 ...

  4. shell 命令 if [ -d filename] 判断文件

    作者:曹毅涵  [ -a FILE ] 如果 FILE 存在则为真. [ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真. [ -c FILE ] 如果 FILE 存在且是一个字特殊 ...

  5. Git合并的代码 不提交服务器的方法

    使用Git下载代码的时候,常遇到合并的情况,然后再上传的时候,系统就会自动把合并代码的过程也上传,有时候会感觉非常的烦Merge remote-tracking branch 'choose_remo ...

  6. GNU Emacs命令速查表

    GNU Emacs命令速查表 第一章  Emacs的基本概念 表1-1:Emacs编辑器的主模式 模式 功能 基本模式(fundamental mode) 默认模式,无特殊行为 文本模式(text m ...

  7. ASP.NET调用cmd命令提示符拒绝访问解决方案

    using System.Diagnostics; public class CmdHelper { private static string CmdPath = @"C:\Windows ...

  8. Css设置img属性让图片水平居中/居左/居右的写法

    图片的居中显示css有很多方法,但在很多情况下有的方法无效,无意发现这个系统的官方处理图片居中,居左,居右的css写法,喜欢的朋友可以收藏下哦 图片的居中显示css有很多方法,但在很多情况下有的方法无 ...

  9. Git基本知识

    一,安装 Ubuntu安装git:sudo apt-get install git-core Centos安装git:yum install git-core 二,配置身份---在提交代码时可以辨别身 ...

  10. sqlite3数据库的简要应用

    Sqlite3数据库升级方案的变化. 1,  若是讲要升级的数据库版本更高,则从低版本数据库中拷贝与新数据库相同字段的内容,其他字段按照默认值创建.A->B->C这样逐个版本升级,每个版本 ...