Порядок аспектов @Async и @Transaction

Используя Spring Boot 2.1.1.RELEASE/Spring Framework 5.1.4, у меня есть приложение с аннотациями @Async и @Transactional, включенными через:

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

При запуске метода, который аннотирован обоими, сначала создается транзакция, а затем начинается асинхронное выполнение. Таким образом, фактическое тело метода не выполняется внутри транзакции.

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

Как я могу настроить spring/аспекты для фактического выполнения в порядке, который имеет смысл, например. начать транзакцию в новом потоке?

Кстати, со старыми Spring Boot 1.5.17/Spring Framework 4.3.20 это действительно работало.

Демонстрация: https://github.com/jaarts/spring-asynctransaction-demo


person Jasper Aarts    schedule 13.02.2019    source источник
comment
Подсказка: аннотации @Enable имеют атрибут order.   -  person M. Deinum    schedule 13.02.2019
comment
Tnx, я пробовал это, но это не имело никакого эффекта.   -  person Jasper Aarts    schedule 13.02.2019
comment
Вы используете режим AspectJ, поэтому у вас включено переплетение времени загрузки или компиляции. Вы пробовали просто поменять порядок аннотаций @Transactionalи @Async? По-видимому, при использовании режима AspectJ (вместо прокси-серверов) он следует порядку аннотаций, объявленному в классе (что из переплетения pov я нахожу вполне логичным).   -  person M. Deinum    schedule 13.02.2019
comment
Я действительно использую плетение времени компиляции. Изменение порядка аннотаций в методе также не повлияло. Я предполагаю, что это связано с порядком, в котором аспекты представлены ткачу.   -  person Jasper Aarts    schedule 13.02.2019
comment
Вы включили их в aop.xml необходимое для плетения? Вы должны иметь возможность контролировать порядок там. Хотя они находятся в порядке асинхронности, а затем транзакции, если смотреть на aop.xml, поставляемый с Spring.   -  person M. Deinum    schedule 13.02.2019
comment
Я не использую никаких пользовательских aop.xml. Насколько я понимаю, этот файл предназначен только для плетения во время загрузки.   -  person Jasper Aarts    schedule 14.02.2019
comment
Время компиляции также, чтобы определить, какие аспекты применить. Spring поставляется с aop.xml, но этот порядок является асинхронным до tx.   -  person M. Deinum    schedule 14.02.2019


Ответы (1)


В Spring 5 асинхронный совет всегда выполняется первым. См. AsyncAnnotationBeanPostProcessor.

public AsyncAnnotationBeanPostProcessor() {
    setBeforeExistingAdvisors(true);
}

После этого в суперклассе в postProcessAfterInitialization, когда советники применяют код, выполняется

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

В @EnableTransactionManagement#order javadoc говорит

Указать порядок исполнения советника по сделкам

но на @EnableAsync

Укажите порядок, в котором следует применять AsyncAnnotationBeanPostProcessor.

person nikita21    schedule 20.08.2019