详细解释Spring事务的传播机制

详细解释Spring事务的传播机制

Spring框架中,事务传播机制是指在一个事务方法调用另一个事务方法时,Spring如何管理这些方法之间的事务边界。Spring提供了七种事务传播行为,以满足不同的业务需求。下面将详细解释每种传播行为及其适用场景,并探讨在特定情况下事务的行为。

1. PROPAGATION_REQUIRED

这是最常用的事务传播行为。如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这种行为确保所有事务操作都在一个统一的事务上下文中执行。

适用场景:大多数情况下使用此传播行为,确保多个事务操作在同一个事务中执行,以保持数据一致性。

什么情况下当前会没有事务?当前是指什么?

在讨论Spring事务传播行为时,“当前”指的是方法执行的上下文,即方法被调用的时刻。当前是否存在事务取决于调用链上的事务配置和执行状态。以下是一些常见情况下当前没有事务的情形:

  1. 外层方法没有事务管理:如果调用事务方法的外层方法没有被事务注解(如@Transactional)标记,那么在调用事务方法时,当前就没有事务存在。

  2. 事务已经提交或回滚:如果前一个事务操作已经完成(提交或回滚),当前就没有活跃的事务。

  3. 非事务调用:从非事务管理的代码路径调用事务方法。例如,从普通的Java方法或第三方库代码中调用事务方法。

  4. 不支持事务的方法:有些方法或组件不支持事务管理,在这些方法中调用事务方法时,当前没有事务。

举例说明

假设有两个方法 methodAmethodB,其中 methodB 被标记为 @Transactional

public class MyService {
    
    public void methodA() {
        // methodA没有事务管理
        methodB();
    }

    @Transactional
    public void methodB() {
        // methodB有事务管理
        // 执行数据库操作
    }
}

在这种情况下,调用 methodA 时:

  • methodA 没有事务管理,因此当前没有事务。
  • methodA 调用 methodB 时,由于 methodA 没有事务,所以 methodB 会创建一个新的事务。

如果将 methodA 也标记为 @Transactional

@Transactional
public void methodA() {
    methodB();
}

此时,调用 methodA 时:

  • methodA 开启了一个事务,因此当前有事务。
  • methodA 调用 methodB 时,methodB 会加入 methodA 的事务,而不是创建新的事务。

如果methodA没有事务,调用了有事务的methodB,那么methodB执行之后的部分,也在事务当中吗?

如果 methodA 没有事务,而调用了有事务的 methodB,那么 methodB 执行之后的部分,不会在事务当中。具体来说,事务的范围仅限于 methodB 的执行过程,methodB 方法返回后,事务就会结束。

下面通过一个具体的例子来说明这个过程:

假设有以下两个方法:

public class MyService {
    
    public void methodA() {
        // 非事务代码
        methodB(); // 调用有事务管理的方法
        // 继续执行非事务代码
    }

    @Transactional
    public void methodB() {
        // 有事务管理的代码
        // 执行数据库操作
    }
}

调用 methodA 时的事务行为如下:

  1. methodA 开始执行,此时没有事务。
  2. methodA 调用 methodB,由于 methodB 被标记为 @Transactional,Spring 会为 methodB 创建一个新的事务。
  3. methodB 在事务中执行其代码(如数据库操作)。
  4. methodB 执行完成后,事务提交或回滚(取决于方法执行的结果和异常情况)。
  5. methodB 返回到 methodA,此时事务已经结束。
  6. methodA 继续执行剩余代码,但此时已经没有事务。

所以,在 methodA 中,methodB 执行的部分是在事务中的,但 methodB 返回后,methodA 剩余的代码是不在事务中的。事务边界由 methodB 的开始和结束决定,事务结束后事务上下文不再存在。

举例:

public class MyService {
    
    public void methodA() {
        System.out.println("methodA: start");
        methodB();
        System.out.println("methodA: end");
    }

    @Transactional
    public void methodB() {
        System.out.println("methodB: in transaction");
        // 这里执行一些数据库操作
    }
}

运行结果:

methodA: start
methodB: in transaction
methodA: end

在这个示例中:

  • “methodA: start” 和 “methodA: end” 的打印是在没有事务的情况下进行的。
  • “methodB: in transaction” 的打印和数据库操作是在事务中的。

这样可以看出,methodB 的事务边界不影响 methodA 的事务状态。

2. PROPAGATION_REQUIRES_NEW

总是启动一个新的事务。如果当前存在事务,则将当前事务挂起。在新的事务执行完成后,恢复先前的事务。

适用场景:适用于需要独立事务的情况,例如记录日志或审计信息,不希望这些操作受到主事务的影响。

3. PROPAGATION_SUPPORTS

支持当前事务。如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。

适用场景:适用于既能在事务内执行,也能在事务外执行的操作。比如,某些只读操作或性能要求不高的操作。

4. PROPAGATION_NOT_SUPPORTED

以非事务方式执行操作。如果当前存在事务,则将当前事务挂起。

适用场景:适用于不需要事务支持的操作,或某些性能要求高、不希望受到事务管理开销影响的操作。

5. PROPAGATION_NEVER

以非事务方式执行。如果当前存在事务,则抛出异常。

适用场景:适用于明确不希望在事务中执行的操作。比如,某些数据库操作可能不支持事务。

6. PROPAGATION_MANDATORY

支持当前事务。如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。

适用场景:适用于必须在现有事务中执行的操作。通常用于一些关键业务逻辑,要求调用者必须在事务中运行。

7. PROPAGATION_NESTED

如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则创建一个新的事务。嵌套事务依赖于底层数据库对保存点(savepoint)的支持。

适用场景:适用于需要部分提交或回滚的复杂业务操作。比如,复杂的财务操作,某些步骤失败后需要回滚到特定点。

参考链接

  • Spring事务管理官方文档
  • Spring事务传播行为解释

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/749477.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IDEA 安装与激活详细教程最新(附最新激活码)2099年亲测有效!

我们先从 IDEA 官网下载 IDEA 2024.1 版本的安装包,下载链接如下: https://www.jetbrains.com/idea/download/ 点击下载(下载Ultimate版),静心等待其下载完毕即可。 激活方式: 正版专属激活码领取

vcruntime140_1.dll是什么东东?vcruntime140_1.dll缺失的8个解决方法

当电脑出现找不到vcruntime140_1.dll,或vcruntime140_1.dll丢失无法打开软件怎么办?小编今天在本文详细为大家介绍解决方法与介绍vcruntime140_1.dll究竟是什么等vcruntime140_1.dll的问题。 一、vcruntime140_1.dll文件是什么 文件概述定义与功能 vcruntime140_…

观测云「可观测性解决方案」荣耀登入华为云官网

继成功上架华为云云商店联营商品后,「观测未来可观测性解决方案」已进一步正式登陆华为云官网,标志着双方合作的深化与拓展。这一全新上架的解决方案是观测云技术实力的集大成之作,为企业提供了一个全面升级的数字化监控观测服务。 观测云&am…

模拟局部下雨的天气思路Mars3d实现参考

目前mars3d里只有下雨滤镜那种,不能表现局部 曲线救国思路参考: 1、根据局部矢量范围求一个外接矩形bbox,根据bbox用turf按照比例尺生成网格(比如50x50公里一个网格) 2、所有的网格再按照矢量范围裁剪一下&#xff0…

「51媒体」湖北地区媒体邀约

传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 媒体宣传加速季,100万补贴享不停,一手媒体资源,全国100城线下落地执行。详情请联系胡老师。 湖北地区拥有网络媒体、电视媒体、报纸杂志、视频媒体等多…

python AI全栈工程师

python AI全栈工程师 前端:Streamlit Streamlit是一个开源的Python库,专为数据科学家和机器学习工程师设计,用于快速构建交互式用户界面。Streamlit功能强大、易于使用,特别适合数据科学家和机器学习工程师快速构建和部署交互式数…

Windows 计划任务 配置 SVN 每天定时更新代码 参照步骤

1. 打开Windows 计划任务 - 创建任务 2. 程序或脚本:配置TortoiseSVN 的安装目录 3. 添加参数: update SVN文件目录 4. 触发器 设置 每天凌晨 1点 5. 常规设置

巡检机器人智能联网,促进工厂自动化

随着工业4.0和智能制造的快速发展,企业引入自动化设备和智能机器人以提高生产效率和降低人工成本已成为大势所趋。其中,巡检机器人作为一种能够在复杂和危险环境中进行自动巡检的设备,受到了广泛关注。如何实现巡检机器人稳定、安全的联网是每…

Java工具包——Lombok

目录 1. maven仓库手动导入依赖注解 1.1 maven仓库引入依赖 1.2 在类上使用Data注解 1.3 在属性上使用Getter与Setter注解 2. EditStarters插件注解 2.1 安装EditStarters插件 2.2 在pom.xml中进行操作 2.3 在java对象类中使用注解 3. lombok工具使用结果查看 3.1…

use embeddings stored in vector db to reduce work for LLM generating response

题意:使用存储在向量数据库中的嵌入来表示,以减少大型语言模型(LLM)生成响应的工作量。 问题背景: Im trying to understand what the correct strategy is for storing and using embeddings in a vector database, …

el-select多选超过两个选项省略

前言 相信大家都遇到过这种情况:Element下拉框多选的时候有个毛病,就是选的数量过多就会把下拉框撑高,从而影响布局;但是如果使用了里面collapse-tags属性,element设置的只显示一个,超过一个就隐藏省略了&…

【Java】微博系统设计:怎么应对热点事件的突发访问压力?

一、问题解析 微博(microblog)是一种允许用户即时更新简短文本(比如140个字符),并可以公开发布的微型博客形式。今天我们就来开发一个面向全球用户、可以支持10亿级用户体量的微博系统,系统名称为“Weitte…

PyCharm左侧项目区域出现淡黄色背景如何解决

PyCharm左侧项目区域出现淡黄色背景如何解决 解决方法: 1、打开pycharm 文件 - > Setting-> 项目 -> 项目结构 2、添加内容根 为 你的项目根目录即可恢复

OpenCV使用forEach的方式来遍历像素值

opencv 4.x新增了forEach的方式遍历像素值&#xff0c;比传统方式略快一些。因为它本身是使用多线程并行的方法来遍历的。从opencv源码能看到这句话&#xff1a; parallel_for_(cv::Range(0, LINES), PixelOperationWrapper(reinterpret_cast<Mat_<_Tp>*>(this), …

iOS之如何创建.a静态库

番外&#xff1a;想要查看如何创建.framework静态库可前往看我​​​​​​​iOS之如何创建.framework静态库-CSDN博客这篇文章。 一、创建静态库项目 ①、打开 Xcode 并创建一个新的 Xcode 项目。 ②、选择 "macOS" -> "Framework & Library" -&…

idea的代码提示插件使用记录

安装ai插件卸载之后&#xff0c;偶尔还是idea一直占用100%&#xff0c;将idea缓存全清理了&#xff0c;重新生成之后就正常了 idea官方插件 下面几个感觉…基本没有感觉 按行提示的偶尔有提示&#xff0c;&#xff08;cpu占用不小&#xff0c;提示不强&#xff09; 缺点&am…

一个易于使用、与Android系统良好整合的多合一游戏模拟器

大家好&#xff0c;今天给大家分享的是一个易于使用、与Android系统良好整合的多合一游戏模拟器 Lemuroid。 Lemuroid 是一个专为Android平台设计的开源游戏模拟器项目&#xff0c;它基于强大的Libretro框架&#xff0c;旨在提供广泛的兼容性和卓越的用户体验。 项目介绍 Lem…

AI在落地企业应用时的“数据幻觉”缘何这么难解决一谈LORA微调与数据质量处理之争

开篇 近年来&#xff0c;随着人工智能技术的飞速发展&#xff0c;越来越多的企业开始将AI落地应用于业务中。然而&#xff0c;不可忽视的是&#xff0c;企业在落地LLM RAG系统时&#xff0c;常常面临一个令人头痛的问题——数据幻觉。 就像透过雾霭的眼睛,看到了一片迷人的景…

ClickHouse-Keeper安装使用

1.rpm 安装 clickhouse-keeper rpm -ivh clickhouse-keeper-23.8.11.28.x86_64.rpm 2.修改keeper的配置文件 vi /etc/clickhouse-keeper/keeper_config.xml修改部分参数 1.可修改日志等存储路径 2.增加监听配置 <listen_host>0.0.0.0</listen_host> 3.server_id…

pycharm terminal终端不能激活 conda 虚拟环境,解决方法

# 1. 确保执行策略已更改 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser# 2. 初始化Conda conda init powershell# 3. 重启PowerShell# 4. 验证Conda初始化 conda --version# 5. 激活Conda环境 conda activate shi_labelme关闭所有的终端&#xff0c;然后重新打开新的终…