当前位置: 首页 > 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

 

http://www.xdnf.cn/news/1038781.html

相关文章:

  • 23. [实用] 扣子(coze)教程 | 小程序UI设计进阶(五)只此一家,标签组件攻略
  • 互联网校招腾讯26届校招暑期实习综合素质测评答题攻略及真题题库
  • monorepo使用指北
  • 123数字人视频剪辑源码搭建部署/数字人视频创作技术开发
  • React配置别名路径完整指南
  • uniapp的app项目,在华为pad上运行,页面显示异常
  • 动目标显示处理解析六(重频参差扩展盲速)
  • static的三种作用
  • 【C++】模拟实现map和set
  • [Linux入门] Linux磁盘管理与文件系统
  • YOLOv3 中的 IoU 计算详解
  • 在Ubuntu linux终端写文件的方法
  • FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
  • 【Zephyr 系列 25】多芯片协同设计:主控 + BLE + LoRa 芯片的统一调度与消息系统
  • 什么是泛型,如何使用它?
  • 动态组件(component)的高级使用
  • PL端DDR3读写(1)
  • 转换专家从格式转换到创意剪辑的全链路解决方案
  • AIGC 基础篇 Python基础(练习1)
  • 板凳-------Mysql cookbook学习 (十--6)
  • Python6.14打卡(day46)
  • StampedLock入门教程
  • 面试问题总结——关于C++(四)
  • 【卫星通信】3GPP标准提案:面向NB-IoT(GEO)场景的IMS信令优化方案-降低卫星通信场景下的语音呼叫建立时延
  • ELK日志文件分析系统——L(Logstash)
  • Flutter 状态管理与 API 调用的完美结合:从理论到实践
  • python实战:使用Python合并PDF文件
  • pyqt5,python开发软件,文件目录如何设置,如何引用,软件架构如何设计
  • 洛谷 P5711:闰年判断
  • 基于Python学习《Head First设计模式》第十一章 代理模式