1

Using Spring Boot 2.1.1.RELEASE / Spring Framework 5.1.4, I have an application with @Async and @Transactional annotations enabled through:

@EnableAsync(mode = AdviceMode.ASPECTJ)
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)

When running a method that is annotated with both, first the transaction is created and then the asynchronous execution starts. So, the actual method body is not executed inside the transaction.

    @Transactional
    @Async
    public void myAsyncMethod() {
        // asynchronous database stuff
    }

How can I configure spring / the aspects to actually execute in an order that makes sense, e.g. start the transaction on the new thread?

On a side note, with the older Spring Boot 1.5.17 / Spring Framework 4.3.20 it actually worked.

Demo: https://github.com/jaarts/spring-asynctransaction-demo

Jasper Aarts
  • 91
  • 1
  • 6
  • Hint, the `@Enable` annotations have an `order` attribute. – M. Deinum Feb 13 '19 at 06:48
  • Tnx, I tried that, but it had no effect. – Jasper Aarts Feb 13 '19 at 07:04
  • YOu are using AspectJ mode so you have either load or compile time weaving enabled. Have you tried simply switching the orde r of the `@Transactional`and `@Async` annotations? Apparently when using AspectJ mode (instead of proxies) it follows the order of the annotations as declared on the class (which from a weaving pov I find quite logical). – M. Deinum Feb 13 '19 at 07:05
  • I'm indeed using compile time weaving. Changing the order of the annotations on the method also had no effect. I'm guessing it has to do with the order in which the aspects are presented to the weaver. – Jasper Aarts Feb 13 '19 at 07:16
  • Have you included them in the `aop.xml` needed for the weaving? You should be able to control the order there. Although they are in the order async then transaction when looking at the `aop.xml` shipped with Spring. – M. Deinum Feb 13 '19 at 07:17
  • I'm not using any custom `aop.xml`. From what I understand, this file is for load-time weaving only. – Jasper Aarts Feb 13 '19 at 23:58
  • Compile time as well to determine which aspects to apply. Spring ships with an `aop.xml` but that ordering is async before tx. – M. Deinum Feb 14 '19 at 13:27

1 Answers1

1

In Spring 5 Async advice is always execited first. See AsyncAnnotationBeanPostProcessor

public AsyncAnnotationBeanPostProcessor() {
    setBeforeExistingAdvisors(true);
}

After that on superclass in postProcessAfterInitialization when advisors aplies code executes

if (this.beforeExistingAdvisors) {
   advised.addAdvisor(0, this.advisor);
}

On @EnableTransactionManagement#order javadoc says

Indicate the ordering of the execution of the transaction advisor

but on @EnableAsync

Indicate the order in which the AsyncAnnotationBeanPostProcessor should be applied.

nikita21
  • 29
  • 3