java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring调用this导致事务失效

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

作者:五阿哥永琪

在 Spring 事务管理 中,如果你在同一个类的方法内部使用 this.xxx() 调用另一个带 @Transactional 的方法,事务很可能会失效,这不是玄学,而是代理机制在背后打盹了,本文就给大家介绍如何解决this调用导致事务失效问题,需要的朋友可以参考下

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

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

失效场景

@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导致事务失效的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文