首页 > 其他分享 >Spring事务的传播行为

Spring事务的传播行为

时间:2024-01-31 14:55:19浏览次数:25  
标签:事务 Spring zzzz 传播 yyyy Propagation 方法 运行

Spring事务的传播行为

1. 概述

当我们遇到下面的情况时,一个service中调用了另一个service中的方法(两个service中都存在事务),此时bservice中的事务就被传播到了aservice中,这样就产生了事务的传播。

@Sercice
public class Aservice{
    @AutoWired
    private Bservice bservice;
    public void order(){
        yyyy();
        bservice.xxxx();
        zzzz();
    }
}

因为两个service都存在事务,那么生成的sql语句可能如下

BEGIN 
    update yyyy;
    -------两个事务的分割线------
        BEGIN 
          updata xxxx;
        COMMIT;
    ---------------------------
    update zzzz;
COMMIT;  

很显然,上面的mysql语句是不支持的。

那么这里就存在一个问题,在mysql中,当第二个begin执行时,会隐式的将第一个事务直接提交了,从而导致aservice中的zzzz()方法最终会以一个无事务的状态去运行。

所以,当【B事务】传播到【A事务中】时,【B事务】要做一下微调,而微调的结果可以分为以下几种情况。

(1)当Aservice中有事务

1. 融入事务

第一种情况,Bservice中的事务融入Aservice中的事务(融入A事务),这种场景是最多的

BEGIN 
    update yyyy;
    -------两个事务的分割线------
          updata xxxx; # B事务融入到A事务中
    ---------------------------
    update zzzz;
COMMIT;  

2. 挂起事务

第二种情况,挂起【A事务】,让【B事务】独立于【A事务】去运行。
当两个事务需要各自独立维护自身事务, 单个事务则无法独立完成,【B事务】启动时可以先给【A事务】暂时挂起,就是阻塞住不给【A事务】继续发送sql,从而让【A事务】无法去提交,B开启一个新的事务,B执行完成后,【A事务】继续。

(1)当Aservice中无事务

1. 以事务的方式运行

第一种情况: 【B事务】以事务的方式运行

select yyyy;
   -------两个事务的分割线------
    BEGIN 
      updata xxxx;
    COMMIT;
   ---------------------------
select zzzz;  

2. 以无事务的方式运行

第一种情况: 【B事务】以无事务的方式运行

select yyyy;
   -------两个事务的分割线------
    select xxxx;
   ---------------------------
select zzzz;  

3. 嵌套事务

BEGIN 
    update yyyy;
    --两个事务的分割线(模拟伪事务)--
    SAVEPOINT a; 
          updata xxxx;
    ROLLBACK TO a;
    ---------------------------
    update zzzz;
COMMIT;  

嵌套过程如下:

  1. 内部SAVEPOINT a的代码如果有问题,则直接回滚至保存点。
  2. 整个事务的提交也不受内部事务(伪事务)的影响。

2. 传播事务

@Transactional(propagation = 下面的值)

  • Propagation.REQUIRED:表示当前方法必须运行在事务中,如果外界有事务存在,方法就会在外界事务中运行,否则,就会启动一个新的事务。REQUIRED就是需要,意思就是B无论如何要有事务。
  • Propagation.SUPPORTS: 表示当前方法不需要事务上下文,如果外界存在事务的话,那么该方法就在外界的事务中运行,否则执行该方法时也不需要事务。
  • Propagation.MANDATORY: (强制性的),表示该方法必须在事务中运行,如果外界事务不存在,就会抛出一个IllegalTransactionStateException异常。
  • Propagation.REQUIRES_NEW: (需要个新的),表示当前方法必须运行在自己的事务中,一个新的事务将被启动,如果外部事务存在,在该方法运行期间,外部事务将会被挂起。
  • Propagation.NOT_SUPPORTED: (不支持事务),表示当前方法不应该运行在事务中,如果存在外部事务,那么在该方法运行期间,会将外部事务挂起,独立的去以非事务的方式去运行当前方法,当前方法运行结束后,再唤醒外部事务。
  • Propagation.NEVER: (不运行在有事务的环境中), 表示当前方法不应该运行在事务的上下文当中,如果该方法外部存在事务,就会抛出IllegalTransactionStateException异常。
  • Propagation.NESTED:(嵌套的) 表示如果存在外部事务,那么该方法将会在外部事务嵌套自己的事务去运行。嵌套的事务可以独立于外部事务进行单独的提交或者回滚,如果外部事务不存在,那么当前方法会自己创造一个事务,在自己创造的事务中运行。

注意: 不同的数据库语言对这种嵌套事务的支持是有所差异的。有的支持,有的不支持。

标签:事务,Spring,zzzz,传播,yyyy,Propagation,方法,运行
From: https://www.cnblogs.com/lunyasen/p/17995659/spring-shi-wu-de-chuan-bo-xing-wei

相关文章

  • handler机制探究——Spring MVC的Handler
    Handler机制主要涉及以下几个方面:Handler类:它是用于处理消息的对象,通常用来在不同的线程之间传递消息。Message类:这是消息对象,包含了有关消息的数据以及目标处理器的引用。MessageQueue类:这是一个存储消息的对象,按照一定的顺序排列。Looper类:它的内部是一个死循环,不断地从Me......
  • SpringBoot 整合多数据源的事务问题
    代码先贴代码:核心就是:Spring给我们提供的一个类AbstractRoutingDataSource,然后我们再写一个切面来切换数据源,肯定要有一个地方存储key还要保证上下文都可用,所以我们使用ThreadLocal来存储数据源的keypom.xml<dependency><groupId>org.springframework.boot</gr......
  • 对比Spring Boot中的JdbcClient与JdbcTemplate
    本文我们一起看看SpringBoot中JdbcClient和JdbcTemplate之间的差异。以下内容使用的Java和SpringBoot版本为:Java21SpringBoot3.2.1假设我们有一个ICustomerService接口:publicinterfaceICustomerService{List<Customer>getAllCustomer();Option......
  • createDelegatingPasswordEncoder只有在spring 5.1.13才能用吗?
    springboot和spring版本对应关系:SpringBoot1.x支持SpringFramework4.x系列,包括4.0、4.1、4.2和4.3等版本。SpringBoot2.x支持SpringFramework5.x系列,包括5.0、5.1和5.2等版本。 下载springboot会一并下载 ......
  • Java21 + SpringBoot3整合springdoc-openapi,自动生成在线接口文档,支持SpringSecurity
    目录前言相关技术简介OpenAPISwaggerSpringfoxspringdocswagger2与swagger3常用注解对比实现步骤引入maven依赖修改配置文件设置api-docs和swagger-ui访问权限定义springdoc配置类修改Controller类和实体类查看效果总结前言近日心血来潮想做一个开源项目,目标是做一款可以适配多......
  • springboot~logback控制日志文件大小与历史个数
    日志本地化,对于每个应用来说都是必须的,最起码第一时间日志是需要本地化的,然后从本地化的日志中再进行推送,例如通过fluentd将日志推到es里,通过kibana工具进行可视化分析。日志文件大小限制对于把日志持久化到磁盘,你需要设置它的占用空间,logback提供了保存文件大小和历史文件数量......
  • Spring 事务管理 基于配置文件
    事务概念:原子性:要么都成功,有一个失败都失败一致性:总量不变(A有100元,B有100元,总量是200元。A把100元转给B,B就有了200元,总量还是200元)隔离性:两人操作同一条数据,不会相互影响持久性:最终提交到数据库后成功搭建事务操作环境进行操作():银行转账例子:1.1、创建数据库,创建表,添加......
  • SpringBoot、SpringCloud相关技术
    一、三层架构 1.1统一业务处理1.2解决三层架构中的结偶,使用了Ioc(控制反转)和DI(依赖注入) 1.3切面编程、事务处理、全局异常处理、Cookie、Session、JWT令牌、阿里云OSS、Mybatis处理数据库二、技术分类说明  2.1SSM三、Web总结四、相关第三方插件https://www......
  • SpringBoot自定义注解+反射实现 excel 导入的数据组装及字段校验
    本次给大家带来的SpringBoot中通过自定义注解+反射实现excel导入数据组装及字段校验的实现方式。这种实现方式其实是很普通、常规的方法,但很多同学在开发过程中,可能却不太容易想到他。当然我也是众多同学中的一员。1背景在前段时间的开发工作中,接手了一个很简单,很普通的开发任务。......
  • 在@KafkaListener启动之前需要做数据的预加载,该在Spring生命周期的哪个阶段做这个事情
    背景说明1、在Spring中消费Kafka数据时,最便捷的方法就是给方法加@KafkaListener注解。在数据消费逻辑中,需要先把一些配置信息预加载到内存中。有同事就提了一个问题:如果保证在消费者执行前,预加载数据的代码一定能执行完?也就是说,要等待数据预加载完成之后,再执行消费逻辑。大部分......