【问题标题】:Spring: How to commit transaction before entering @AfterReturning adviceSpring:如何在进入@AfterReturning 建议之前提交事务
【发布时间】:2018-02-20 20:17:31
【问题描述】:

我有一个事务服务类:

@Service
@Transactional(...)
public class MyService() {

    public void myFunc() { 
       // some code
    }

}

还有以下看点:

@Aspect
public class MyAspect() {

    @AfterReturning(value = "execution(...") // pointcut matching myFunc()'s signature
    public void doSomethingAfterMyFunc() { 
       // some code
    }

}

我面临的问题是,在输入@AfterReturning 建议时,从执行myFunc() 创建的事务尚未提交,因此建议共享相同的事务。根据我的阅读,这种行为是意料之中的,但出于我的目的,我需要相反的情况——有没有办法在输入建议之前提交 myFunc() 的事务?

提前致谢!

【问题讨论】:

  • @EnableTransactionManagement@EnableAspectJAutoProxy 上显式设置order。确保后者先行。

标签: java spring service transactions aop


【解决方案1】:

这是因为@Transactional 方面而发生的,因此您的代码中有两个方面,因此您必须按照https://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-ataspectj-advice-ordering 的说明设置Order

在您的代码中,您可以设置自己的方面MyAspect 的顺序,如下所示:

@Aspect
@Order(1)
public class MyAspect() {
 //your code here
}

通过将其顺序指定为 1 并且由于规则是这样的:

在从joinpoint出来的路上,order值最高的advice 首先执行。

@Transactional 方面将在你之前执行,因此myFunc 将被提交,然后doSomethingAfterMyFunc 将被执行。

【讨论】:

  • 你说的似乎合乎逻辑,我试过了。但是还是不行。
  • 好吧,我们在项目中遇到了完全相同的问题,我们通过在Aspect 中设置Order 来解决它。您是否还按照@M.Deinum 的建议在@EnableTransactionManagement 中设置了订单?如果你这样做,它必须高于 1。虽然默认值已经远远大于 1。它应该也适用于你的项目。
  • 是的,我什么都试过了。在一天结束时,我最终使用 @TransactionalEventListener 而不是 AfterReturning 建议来运行 myFunc() 完成后所需的代码。
  • 我知道这是旧的,但 @Transactional 使用最低优先级 (Integer.MAX_VALUE)。因此设置顺序将不再起作用,因为任何数字的优先级都高于 Integer.MAX_VALUE。您可以更改事务的默认优先级,但我喜欢您使用 @TransactionalEventListener better 的想法
猜你喜欢
  • 1970-01-01
  • 2016-10-23
  • 1970-01-01
  • 1970-01-01
  • 2015-01-10
  • 2011-10-08
  • 2020-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多