如何解决this调用导致事务失效?

📅 发布时间:2026/7/6 5:43:11 👁️ 浏览次数:
如何解决this调用导致事务失效?
文章目录一、为什么 this 调用会导致事务失效❌ 失效场景二、如何保证事务生效✅ 方案一通过 Spring 代理对象调用推荐⭐⭐⭐⭐⭐✔ 方法1注入自身代理✔ 方法2使用 AopContext 获取代理需开启暴露代理✅ 方案二拆分到不同 Service最佳实践⭐⭐⭐⭐⭐✅ 方案三使用编程式事务不常用在Spring 事务管理中如果你在同一个类的方法内部使用this.xxx()调用另一个带Transactional的方法事务很可能会失效。这不是玄学而是代理机制在背后“打盹了”。我们一步步拆开看。一、为什么this调用会导致事务失效Spring 的声明式事务基于AOP 代理实现Spring 为你的 Bean 创建一个代理对象事务逻辑在代理对象中织入只有通过代理对象调用方法才会触发事务❌ 失效场景ServicepublicclassOrderService{publicvoidcreateOrder(){// 直接调用this.saveOrder();// ❌ 不经过代理}TransactionalpublicvoidsaveOrder(){// 数据库操作}}调用路径createOrder()→this.saveOrder()这里没有经过 Spring 代理 → 事务不会生效。二、如何保证事务生效✅ 方案一通过 Spring 代理对象调用推荐⭐⭐⭐⭐⭐✔ 方法1注入自身代理ServicepublicclassOrderService{AutowiredprivateOrderServiceorderService;// 注入代理对象publicvoidcreateOrder(){orderService.saveOrder();// ✅ 通过代理调用}TransactionalpublicvoidsaveOrder(){}} 原理Spring 注入的是代理对象而不是原始对象。✔ 方法2使用 AopContext 获取代理需开启暴露代理① 开启配置EnableAspectJAutoProxy(exposeProxytrue)② 调用方式publicvoidcreateOrder(){((OrderService)AopContext.currentProxy()).saveOrder();} 适合不想注入自身的场景。✅ 方案二拆分到不同 Service最佳实践⭐⭐⭐⭐⭐这是企业项目最推荐的结构设计。ServicepublicclassOrderService{AutowiredprivateOrderTxServiceorderTxService;publicvoidcreateOrder(){orderTxService.saveOrder();}}ServicepublicclassOrderTxService{TransactionalpublicvoidsaveOrder(){}}✔ 更清晰✔ 职责单一✔ 更利于维护 扩展 这是大型系统常见架构方式。✅ 方案三使用编程式事务不常用AutowiredprivateTransactionTemplatetransactionTemplate;publicvoidcreateOrder(){transactionTemplate.execute(status-{saveOrder();returnnull;});}适用于需要精细控制事务复杂业务流程但日常开发不推荐优先使用。