Spring调用this导致事务失效的三种解决方案

 更新时间:2026年02月26日 09:22:15   作者:五阿哥永琪  
在 Spring 事务管理 中,如果你在同一个类的方法内部使用 this.xxx() 调用另一个带 @Transactional 的方法,事务很可能会失效,这不是玄学,而是代理机制在背后打盹了,本文就给大家介绍如何解决this调用导致事务失效问题,需要的朋友可以参考下

一、为什么this调用会导致事务失效?

Spring 的声明式事务基于 AOP 代理 实现:

  • Spring 为你的 Bean 创建一个 代理对象
  • 事务逻辑在代理对象中织入
  • 只有 通过代理对象调用方法 才会触发事务

失效场景

@Service
public class OrderService {

    public void createOrder() {
        // 直接调用
        this.saveOrder();   // ❌ 不经过代理
    }

    @Transactional
    public void saveOrder() {
        // 数据库操作
    }
}

调用路径:

createOrder() → this.saveOrder()

这里没有经过 Spring 代理 → 事务不会生效。

二、如何保证事务生效?

方案一:通过 Spring 代理对象调用(推荐⭐⭐⭐⭐⭐)

方法1:注入自身代理

@Service
public class OrderService {

    @Autowired
    private OrderService orderService; // 注入代理对象

    public void createOrder() {
        orderService.saveOrder(); // ✅ 通过代理调用
    }

    @Transactional
    public void saveOrder() {
    }
}

原理:Spring 注入的是代理对象,而不是原始对象。

方法2:使用 AopContext 获取代理(需开启暴露代理)

① 开启配置

@EnableAspectJAutoProxy(exposeProxy = true)

② 调用方式

public void createOrder() {
    ((OrderService) AopContext.currentProxy()).saveOrder();
}

适合不想注入自身的场景。

方案二:拆分到不同 Service(最佳实践⭐⭐⭐⭐⭐)

这是企业项目最推荐的结构设计。

@Service
public class OrderService {

    @Autowired
    private OrderTxService orderTxService;

    public void createOrder() {
        orderTxService.saveOrder();
    }
}

@Service
public class OrderTxService {

    @Transactional
    public void saveOrder() {
    }
}

✔ 更清晰
✔ 职责单一
✔ 更利于维护 & 扩展

这是大型系统常见架构方式。

方案三:使用编程式事务(不常用)

@Autowired
private TransactionTemplate transactionTemplate;

public void createOrder() {
    transactionTemplate.execute(status -> {
        saveOrder();
        return null;
    });
}

适用于:

  • 需要精细控制事务
  • 复杂业务流程

但日常开发不推荐优先使用。

以上就是Spring调用this导致事务失效的三种解决方案的详细内容,更多关于Spring调用this导致事务失效的资料请关注脚本之家其它相关文章!

相关文章

  • Java的validation参数校验代码实例

    Java的validation参数校验代码实例

    这篇文章主要介绍了Java的validation参数校验代码实例,Validation参数校验是指在程序运行中对传进来的参数进行合法性检查,以保证程序的正确性和安全性,需要的朋友可以参考下
    2023-10-10
  • 详解Java中Dijkstra(迪杰斯特拉)算法的图解与实现

    详解Java中Dijkstra(迪杰斯特拉)算法的图解与实现

    Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。本文将详解该算法的图解与实现,需要的可以参考一下
    2022-05-05
  • 基于JDK动态代理原理解析

    基于JDK动态代理原理解析

    这篇文章主要介绍了基于JDK动态代理原理解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • java中日期格式化的大坑

    java中日期格式化的大坑

    这篇文章主要介绍了java中日期格式化的大坑,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • Log4j2 重大漏洞编译好的log4j-2.15.0.jar包下载(替换过程)

    Log4j2 重大漏洞编译好的log4j-2.15.0.jar包下载(替换过程)

    Apache 开源项目 Log4j 的远程代码执行漏洞细节被公开,由于 Log4j 的广泛使用,该漏洞一旦被攻击者利用会造成严重危害,下面小编给大家带来了Log4j2 重大漏洞编译好的log4j-2.15.0.jar包下载,感兴趣的朋友一起看看吧
    2021-12-12
  • Java 对象序列化 NIO NIO2详细介绍及解析

    Java 对象序列化 NIO NIO2详细介绍及解析

    这篇文章主要介绍了Java 对象序列化 NIO NIO2详细介绍及解析的相关资料,序列化机制可以使对象可以脱离程序的运行而对立存在,需要的朋友可以参考下
    2017-02-02
  • Java编程实现A*算法完整代码

    Java编程实现A*算法完整代码

    这篇文章主要介绍了Java编程实现A*算法完整代码,简单介绍了a星算法,然后分享了完整测试代码,具有一定借鉴价值,需要的朋友可以参考下。
    2017-11-11
  • Maven的POM常用标签详解

    Maven的POM常用标签详解

    本文介绍maven中pom常用标签作用和用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-09-09
  • Springboot中如何自动转JSON输出

    Springboot中如何自动转JSON输出

    这篇文章主要介绍了Springboot中如何自动转JSON输出,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • Java并发编程:CountDownLatch与CyclicBarrier和Semaphore的实例详解

    Java并发编程:CountDownLatch与CyclicBarrier和Semaphore的实例详解

    这篇文章主要介绍了Java并发编程:CountDownLatch与CyclicBarrier和Semaphore的实例详解的相关资料,需要的朋友可以参考下
    2017-09-09

最新评论