前言

Spring在TransactionDefinition接口中规定了7种类型的事务传播行为。事务传播行为是Spring框架独有的事务增强特性,他不属于的事务实际提供方数据库行为。这是Spring为我们提供的强大的工具箱,使用事务传播行可以为我们的开发工作提供许多便利。但是人们对他的误解也颇多,你一定也听过“service方法事务最好不要嵌套”的传言。要想正确的使用工具首先需要了解工具。

基础概念

1. 什么是事务传播行为?

事务传播行为用来描述由某一个事务传播行为修饰的方法被嵌套进另一个方法的时事务如何传播。

用伪代码说明:

 @Transaction(Propagation=XXX)
public void methodA(){
methodB();
//doSomething
} public void methodB(){
//doSomething
}

methodA中存在事务,他又调用了methodB。methodB事物的一些特性由methodA决定,这就是事务的传播行为。

2. Spring中七种事务传播行为

事务传播行为类型 说明
PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

定义非常简单,也很好理解,下面我们就进入代码测试部分,验证我们的理解是否正确。

代码验证

第一种情况。内部均为 propagation = Propagation.REQUIRED

 @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ)
@Override
public void testTransactional() {
int insert = downloadImgDao.test1();
log.info("insert1 = {}", insert); insert = downloadImgDao.test2();
log.info("insert2 = {}", insert);
} @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ)
@Override
public int test1() {
DownloadImg downloadImg = new DownloadImg();
downloadImg.setId(666L);
downloadImg.setLink("张三");
downloadImg.setLinkname("16");
int res = downloadImgMapper.insertSelective(downloadImg);
log.info("res1 = {}", res);
return res;
} @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ)
@Override
public int test2() {
DownloadImg downloadImg = new DownloadImg();
downloadImg.setId(888L);
downloadImg.setLink("李四");
downloadImg.setLinkname("18");
int res = downloadImgMapper.insertSelective(downloadImg);
log.info("res2 = {}", res); int i = 5 / 0;
return res;
}

张三,李四插入均失败。

第二种情况。内部一种为 propagation = Propagation.REQUIRED,一种为Propagation.REQUIRES_NEW

 @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.REPEATABLE_READ)
@Override
public int test1() {
DownloadImg downloadImg = new DownloadImg();
downloadImg.setId(666L);
downloadImg.setLink("张三");
downloadImg.setLinkname("16");
int res = downloadImgMapper.insertSelective(downloadImg);
log.info("res1 = {}", res);
return res;
} @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ)
@Override
public int test2() {
DownloadImg downloadImg = new DownloadImg();
downloadImg.setId(888L);
downloadImg.setLink("李四");
downloadImg.setLinkname("18");
int res = downloadImgMapper.insertSelective(downloadImg);
log.info("res2 = {}", res); int i = 5 / 0;
return res;
}

张三插入成功,李四插入失败。

第三种情况。内部均为Propagation.REQUIRES_NEW

跟我们现象的是一样的,如果哪个test异常,哪个就失败,无异常的就成功。

还有一种情况是,外围抛异常了,内部都不抛异常,两种内部插入也都会成功。

结论

本程序是实验了PROPAGATION_REQUIRED以及Propagation.REQUIRES_NEW。

事务默认以PROPAGATION_REQUIRED来隔离。

1: 如果内部是PROPAGATION_REQUIRED隔离级别,内部只要一个方法出错,那么整个事务都会回滚。

2: 如果内部有方法以Propagation.REQUIRES_NEW来隔离。那么他会创建一个新的事务来运行,如果他抛异常了,并不会影响其他事务的以及外部的事务。

spring事务官方文档:https://docs.spring.io/spring/docs/5.2.6.RELEASE/spring-framework-reference/data-access.html#tx-propagation

参考文档:https://segmentfault.com/a/1190000013341344

Spring事务的传播属性的更多相关文章

  1. 关于Spring 事务管理传播属性的配置及作用-嵌套事务

    先了解事务的7种传播属性: PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务.这是最常见的选择. PROPAGATION_SUPPORTS -- 支持当前 ...

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

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

  3. [Spring] Spirng中的AOP进行事务的传播属性和事务隔离级别

    通知注解 前置通知(@Before):在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常) 返回后通知(@AfterReturning):在某连接点 ...

  4. 事务的传播属性及隔离级别 Spring

    事务的传播属性(Propagation) REQUIRED ,这个是默认的属性 Support a current transaction, create a new one if none exis ...

  5. Spring事务的传播行为 @Transactional

    Spring事务的传播行为http://blog.csdn.net/cuker919/article/details/5957209 在service类前加上@Transactional,声明这个se ...

  6. Spring事务的传播行为 @Transactional(转)

    Spring事务的传播行为 在service类前加上@Transactional,声明这个service所有方法需要事务管理.每一个业务方法开始时都会打开一个事务. Spring默认情况下会对运行期例 ...

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

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

  8. Spring事务的传播:PROPAGATION_REQUIRED

    PROPAGATION_REQUIRED-- 支持当前事务,如果当前没有事务,就新建一个事务.这是最常见的选择. ServiceA { void methodA() { ServiceB.method ...

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

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

随机推荐

  1. 题解 P2421 【[NOI2002]荒岛野人】

    我的第一道数论紫题 首先,我们先看两个野人,他们相遇的充要条件是 \(C_i+P_i\times k\equiv C_j+P_j\times k\;(mod\;M)\) 其中\(k\)是第几年,且\( ...

  2. 数据库范式1NF 2NF 3NF详细阐述

    范式:关系数据库中的关系是要满足一定要求的,满足不同程度要求的不同范式.满足最低要求的叫第一范式,简称1NF ,在第一范式中满足进一步要求的为第二范式,其余以此类推.通俗来说是满足数据库关系表中的一套 ...

  3. HTML5新特性 websocket(重点)--多对多聊天室

    一.html5新特性  websocket(重点)--多对多聊天室 HTTP:超文本传输协议 HTTP作用:传输网页中资源(html;css;js;image;video;..) HTTP是浏览器搬运 ...

  4. sql语句 怎么从一张表中查询数据插入到另一张表中?

    sql语句 怎么从一张表中查询数据插入到另一张表中?  ----原文地址:http://www.phpfans.net/ask/MTc0MTQ4Mw.html 比如我有两张表 table1 字段 un ...

  5. Spring 中基于 AOP 的 @AspectJ

    Spring 中基于 AOP 的 @AspectJ @AspectJ 作为通过 Java 5 注释注释的普通的 Java 类,它指的是声明 aspects 的一种风格. 通过在你的基于架构的 XML ...

  6. 设计模式:Filter+Servlet+反射

    传统设计 分类管理需要:增加,删除,编辑,修改,查询5个服务端功能. 一个路径对应一个Servlet的思路,就需要设计5个Servlet类,并且在web.xml中配置5个路径. CategoryAdd ...

  7. 如何快速全面掌握Kafka?这篇文章总结了

    Kafka 是目前主流的分布式消息引擎及流处理平台,经常用做企业的消息总线.实时数据管道,本文挑选了 Kafka 的几个核心话题,帮助大家快速掌握 Kafka,包括: Kafka 体系架构 Kafka ...

  8. C# 数据操作系列 - 16 SqlSugar 完结篇

    0. 前言 前一篇我们详细的介绍了SqlSugar的增删改查,那些已经满足我们在日常工程开发中的使用了.但是还有一点点在开发中并不常用,但是却非常有用的方法.接下来让我们一起来看看还有哪些有意思的内容 ...

  9. CSS基础选择器总结

    基础选择器 作用 特点 使用情况 用法 标签选择器 可以选出所有相同的标签,比如p 不能差异化选择 较多 p {color:red;} 类选择器 可以选出1个或多个标签 可以根据需求选择 非常多 .n ...

  10. vue-cli2 使用cdn资源

    vue-cli2 引入固定cdn资源操作记录 vue引入cdn也不是什么神奇的操作,但是自己之前一直没有尝试过,这次正好项目优化需要,所以,实操一波,特此记录 本次cnd引入了如下资源 vue vue ...