当前位置: 首页 > news >正文

有关Spring事务的传播机制

这是一个非常常见的关于 Spring 事务传播机制 的问题,核心问题是:

在同一个类中,方法 A 调用方法 B,而方法 B 上有 @Transactional 注解。当调用方法 A 时,如果发生异常,方法 B 的事务会生效吗?


✅ 简短回答:

 

📌 示例代码说明

@Service
public class MyService {public void methodA() {// 做一些操作methodB();  // 内部调用methodB}@Transactionalpublic void methodB() {// 数据库操作}
}

❗️问题:

  •  

🤔 为什么事务不生效?

因为 Spring 的事务是通过 动态代理(JDK Proxy 或 CGLIB) 实现的:

  •  

✅ 如何解决这个问题?

✅ 方案一:将方法拆分到不同的类中

把 methodB() 放到另一个 Service 类中:

@Service
public class MyService {@Autowiredprivate AnotherService anotherService;public void methodA() {// 做一些操作anotherService.methodB();  // 外部调用}
}@Service
public class AnotherService {@Transactionalpublic void methodB() {// 数据库操作}
}

✅ 这样事务就会生效了。


✅ 方案二:通过 AopContext.currentProxy() 获取代理对象(慎用)

你可以通过以下方式获取当前类的代理对象来调用 methodB()

@Service
public class MyService implements ApplicationContextAware {private static ApplicationContext applicationContext;@Transactionalpublic void methodB() {// 数据库操作}public void methodA() {// 获取当前类的代理对象MyService proxy = (MyService) AopContext.currentProxy();proxy.methodB();  // 使用代理调用}@Overridepublic void setApplicationContext(ApplicationContext ctx) {applicationContext = ctx;}
}

⚠️ 注意事项:

  •  

🔁 补充:事务传播行为(Propagation Behavior)

如果你希望方法B的行为能被方法A控制,可以指定事务传播行为,例如:

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodB() {// 总是开启一个新事务
}

 

✅ 总结

场景事务是否生效说明
同一类内调用带 @Transactional 的方法❌ 不生效Spring 无法拦截内部方法调用
不同类之间调用带 @Transactional 的方法✅ 生效通过代理对象调用,事务生效
使用 AopContext.currentProxy() 调用✅ 可以生效需要设置 expose-proxy=true

 

相关文章:

  • Java 单例模式实现方式
  • 基于51单片机的校园打铃及灯控制系统
  • 内容风控概念基础
  • Vue 3 砸金蛋互动抽奖游戏
  • Gartner《Build Scalable Data Products With This Step-by-Step Framework》学习报告
  • 互联网校招腾讯26届校招暑期实习综合素质测评答题攻略及真题题库
  • jQuery.ajax() 方法核心参数详解
  • Vue3中v-bind=“$attrs“应用实例
  • 【学习笔记】Langchain基础(二)
  • 日志分割问题
  • 从大数据到大模型:我们是否在重蹈覆覆辙
  • 数据库连接池深度研究分析报告
  • 学习昇腾开发的第二天--PC机远程登录开发板
  • 2.4 机器人运动控制
  • leetcode_503 下一个更大元素
  • 从汇编的角度揭开C++ this指针的神秘面纱(上)
  • AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年6月14日第108弹
  • Java线程安全计数器实现方案
  • tcp, udp , 与 select .
  • pycharm2020.2版本给项目选择了虚拟环境解释器,项目文件都运行正常,为什么terminal文件路径的前面没有虚拟解释器的名称
  • 宝鸡手机网站开发/少儿编程
  • 南乐政府门户网站建设/seo经验是什么
  • 公司网站制作商/站长之家网站模板
  • 网站突然不能访问/优化设计七年级下册语文答案
  • 兴安盟做网站公司/阿里巴巴推广
  • 怎么做赌钱网站/营销策划机构