'Why is Spring @Transactional unreliable with AspectJ?

TLDR: this project reproduces the issue: https://github.com/moreginger/aspectj-no-tx

Edit: Above now reproduced without jooq i.e. using plain JDBC.

Edit: Spring bug - https://github.com/spring-projects/spring-framework/issues/28368


I've been trying to use AspectJ to weave Spring @Transactional for a Kotlin codebase. I've seen it working with both load-time and compile-time weaving (the latter using io.freefair.aspectj.post-compile-weaving). However, when I wrote a test that the transaction would be unwound after an exception something strange happened: the test would sometimes fail. It turned out that it always failed on the first test suite run, then the second time around it would run first (due to failing the first time) and pass. After much investigation, a "minimal" case in my codebase is (in the same suite run):

  • Runs a test which calls a method marked @Transactional on an @Autowired bean.
  • Runs a test in a different class that calls another method marked @Transactional on a different @Autowired bean, which will make some changes and then throw an exception. Assert that the changes made aren't visible. This fails.

Then if you run this suite again it runs the second test first due to failing the first time and passes. It continues to run in this order and pass until something else fails or gradle clean is run. (Note that to avoid the order swapping you can make the first test also fail).

The same thing happens whether I use load-time or compile-time weaving.

How can this be? Especially with compile-time weaving the transactions have been incorporated into the class files. How can accessing a different @Transactional method cause one that we access later to stop being @Transactional o_O ? I've verified that simply removing @Transactional from the first "fixes" the issue.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source