Spring 事务传播和自调用行为

news2024/11/13 14:37:49

为了方便讲解,这里的A、B、C类都是Spring管理的Bean。

自调用行为

自调用行为示例

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
​
@Component
public class B {
    @Autowired
    public void b() {
        this.c();
    }
    
    @Transactional
    public void c() {
​
    }
}

不生效的原因

代码示例 B.b() 直接调用 B.c() 是一个典型的自调用情况。在这种情况下,即使 B.c() 方法有 @Transactional 注解,由于是在同一个类的内部直接调用,事务注解不会被 Spring 的代理机制捕获,因此不会生效。

在 Spring 的 AOP(面向切面编程)架构中,事务管理是通过代理(Proxy)来实现的。当一个方法被调用时,如果这个方法从外部(即通过 Spring 容器管理的 Bean)调用,并且配置了 @Transactional,Spring 会通过代理来拦截这个调用,然后根据 @Transactional 的属性来开始、加入、挂起或结束事务。但如果这个调用是从同一个类的内部发生的,比如一个方法直接调用同一个类中的另一个方法,这种调用就不会经过代理,Spring 无法施加事务管理的逻辑。

自调用行为解决方案

通过 Spring ApplicationContext 获取代理

可以让 Spring 注入自身的 ApplicationContext,并使用它来获取当前 Bean 的代理,然后通过代理来调用方法。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
​
@Component
public class B {
    @Autowired
    private ApplicationContext applicationContext;
​
    public void b() {
        B b = applicationContext.getBean(B.class);
        b.c();
    }
​
    public void c() {
        // Transactional code
    }
}
使用 AopContext.currentProxy()

这是一个更简单的方式,但需要在 Spring 配置中启用 exposeProxy=true。然后你可以通过 AopContext.currentProxy() 来获取当前对象的代理并进行调用。

要启用 exposeProxy,需要在 Spring 的配置中设置:

@EnableAspectJAutoProxy(exposeProxy = true)
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
​
@Component
public class B {
    public void b() {
        ((B) AopContext.currentProxy()).c();
    }
​
    @Transactional
    public void c() {
        // Transactional code
    }
}

正确的事务传播行为

2. 创建三个Bean类

接下来,我们创建三个类,每个类都有不同的方法,演示事务的传播:

A类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
​
@Service
public class A {
    @Autowired
    private B b;
​
    @Transactional
    public void methodA() {
        System.out.println("Inside A.methodA");
        b.methodB();
    }
}
B类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
​
@Service
public class B {
    @Autowired
    private C c;
​
    @Transactional
    public void methodB() {
        System.out.println("Inside B.methodB");
        c.methodC();
    }
}
C类
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
​
@Service
public class C {
​
    @Transactional
    public void methodC() {
        System.out.println("Inside C.methodC");
        // 这里可以添加实际的数据库操作代码
    }
}

解释

在这个设置中:

  • 当 methodA 被调用时,它在 A 类的事务环境中开始执行。

  • A.methodA 调用 B.methodB,B.methodB 进一步调用 C.methodC。由于每个方法都通过Spring的代理调用,每个方法都有 @Transactional 注解,这保证了事务在整个调用链中得以正确管理。

  • 如果有需要,每个方法可以根据其事务传播设置独立地控制事务行为。在这个示例中,我们没有明确设置传播行为,所以它们默认使用 Propagation.REQUIRED,这意味着它们会加入到现有的事务中。

为什么这里的methodB没有明写事务,但是methodA、methodB、methodC都有事务

因为A.methodA事务传播到B.methodB,B.methodB传播到C.methodC,因为B.methodB调用C.methodC不属于自调用,所以Spring能捕获到并且进行添加事务。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Python报错已解决】“ModuleNotFoundError: No module named ‘torch_scatter‘”

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 引言:一、问题描述1.1 报错示例:1.2 报错分析:1.3 解决思路: 二、解决…

【golang-入门】环境配置、VSCode开发环境配置

golang介绍基础信息 windows环境配置安装包下载安装环境变量设置检查 VSCode开发配置插件配置在 Visual Studio Code 中安装通义灵码go hello word 参考资料 golang介绍 基础信息 golang官网:https://go.dev/golang学习网:https://studygolang.com/使用…

本地服务器使用Docker搭建Nacos动态服务管理平台并实现远程访问

文章目录 前言1. Docker 运行Nacos2. 本地访问Nacos3. Linux安装Cpolar4. 配置Nacos UI界面公网地址5. 远程访问 Nacos UI界面6. 固定Nacos UI界面公网地址7. 固定地址访问Nacos 前言 本文主要介绍如何本地部署动态服务发现、配置管理和服务管理平台 Nacos ,并结合…

WCDMA 辅同步信号S_SCH介绍,MATLAB实现

本期主要介绍一下WCDMA辅同步信号S_SCH实现和映射,从公式生成开始介绍,最后用MATLAB实现,让大家了解对比一下3G时代辅同步信号和前面介绍的4G、5G和2G时代的辅同步信号共同点和不同点,不管在什么时候辅同步信号都要遵循一个码要正…

【3.9】贪心算法-解最低加油次数

一、题目 汽车从起点出发驶向目的地,该目的地位于出发位置东面 target 英里处。 沿途有加油站,用数组 stations 表示。其中 stations[i] [positioni, fueli] 表示第 i 个加油站位于出发位置东面 positioni 英里处,并且有 fueli 升汽油。 假设…

bladeX默认审批流flowable如何设置

下面就是流程图必须得写 ${taskUser} 你要配什么 就给审批流的service传什么

自己动手写CPU_step6.1_算数运算指令

序 接上篇的加减指令,本篇主要实现CLZ、CLO、SLT等指令。 CLZ:从最高位开始数0的个数直到遇到1。 例:0x0000,0001 CLZ指令结果:31 0x8000,ffff CLZ指令结果是0 CLZ:从高位开始数1的个数直到遇到0…

告别繁琐,拥抱FileGee——你的高效生活助手!

前言 科技决不是一种自私自利的享乐。有幸能够致力于科技研究的人,首先应该拿自己的学识为人类服务。——马克思,这句话提醒我们,在数字化时代,高效管理自己的数据与时间同样重要。FileGee,正是在这样的背景下应运而生…

【最大上升子序列和】

题目 前置芝士 1. erase 函数 erase(iterator pos):删除单个元素,其中 pos 是要删除元素的迭代器。 erase(iterator first, iterator last):删除从 first 到 last(不包括 last)之间的所有元素。 2. unique 函数 uniqu…

emmc协议

一、简介 1.1 简介 嵌入式多媒体卡(Embedded Multimedia Card, eMMC)是由 JEDEC 协会所订立,将 MMC controller 和 NAND Flash 封装到一个芯片中,简化存储器的使用和电路板的设计。 1.2 信号 singledescriptionclkclockdata…

Qt22双缓冲机制

Qt22双缓冲机制 知识点drawwidgetdrawwidget.hdrawwidget.cpp mainwindowmainwindow.hmainwindow.cpp main.cpp运行图 知识点 双缓冲就是在内存区申请一块缓存;然后显卡直接从这块内存读取数据.。 这样就不用鼠标边画,经过IO来读取这个环节;…

2024杭电6

1001.造花(简单版) 题意: 菊花图:n-1个节点都连接同一节点的树。 给定一棵树,删掉一个节点和连向这个点的所有边,使剩下两个连通块都构成菊花图,问是否可以做到。 题解: 菊花图只有…

算法练习题07:无重复字符的最长子串

我们可以使用 滑动窗口 的方法来解决这个问题。这是一种高效的算法,能在 O(n) 的时间复杂度内完成任务。以下是具体的解题思路: 1. 滑动窗口的概念 滑动窗口的想法是使用两个指针(通常称为左指针 i 和右指针 j)来表示一个窗口。…

秋招/春招投递公司记录表格

最近在准备秋招,在各个平台投递秋招简历,什么官网,邮箱,boss,应届生各个平台上,投递的平台比较多,比较乱,因此自己想将这些平台投递记录都收集到一个表格上,所以在腾讯文…

基于Java+MySQL实现在线书店订购系统

一、引言 1.1 编写目的 编写详细设计说明书是软件开发过程必不可少的部分,其目的是为了使开发人员在完成概要设计说明书的基础上完成概要设计规定的各项模块的具体实现的设计工作。同时也是开发人员和最终客户进行需求交流的有效手段。 1.2 背景 开发软件系统名…

数据结构——排序上

1.排序的概念及其运用 1.1排序的概念 排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作 稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录&a…

多目标应用:基于自组织分群的多目标粒子群优化算法(SS-MOPSO)的移动机器人路径规划研究(提供MATLAB代码)

一、机器人路径规划介绍 移动机器人(Mobile robot,MR)的路径规划是 移动机器人研究的重要分支之,是对其进行控制的基础。根据环境信息的已知程度不同,路径规划分为基于环境信息已知的全局路径规划和基于环境信息未知或…

美国海外仓可以用哪家海外仓系统好?

随着全球贸易的增长,美国已经成为了海外仓储业务的一个重要市场。美国海外仓的数量不断增加,竞争也愈加激烈。为应对这种竞争,并优化仓储和供应链管理,WMS(仓库管理系统)成为了海外仓的重要工具。 一、WMS…

Wx64ST:一款轻松可修改的C语言Shellcode模板

关于windows_x64_shellcode_template windows_x64_shellcode_template简称为Wx64ST,它是一款功能强大的Shellcode模板,该模板基于C语言编写,其简单、可扩展和易于修改等特性可以帮助广大安全研究人员轻松开发适用于Windows x64的Shellcode。…