Spring-транзакция не создается при вызове метода @Transactional через отражение - PullRequest
1 голос
/ 09 января 2020

У меня есть класс, который вызывает метод publi c для другого класса через отражение. Вызывающий класс уже имеет активную транзакцию, и метод publi c в вызываемом классе помечается

@Transactional(propagation = Propagation.REQUIRES_NEW)
    public void handleProcess() { ..}

Вызов выглядит как

Runnable runnable = null;
Method handleMethod = config.handleProcessMethod;
            Object handler = autowireHandler(process);
            runnable = () -> {
                LOGGER.info("executing method {} on {}",handleMethod,handler);
                handleMethod.invoke(handler);
            };
runnable.run();

Метод вызывается правильно , но журнал указывает, что он участвует в текущей транзакции, а не создает новую.

08:54:33.452 [process-executor-2] DEBUG o.springframework.orm.jpa.JpaTransactionManager - Found thread-bound EntityManager ... for JPA transaction
08:54:33.453 [process-executor-2] DEBUG o.springframework.orm.jpa.JpaTransactionManager - Participating in existing transaction

Редактировать: на самом деле журналы сверху создаются в вызванный метод, вызванный хранилищем JPA, а не до него. Похоже, что аннотация @Transactional вообще не обрабатывается.

Отражение заставляет пружину пропускать аннотацию @Transactional? Мне нужно, чтобы вызванный метод использовал свою собственную транзакцию, чтобы она фиксировалась до возврата из вызова.

1 Ответ

1 голос
/ 09 января 2020

Аннотация сообщает Spring, что обернуть прокси-сервером, который реализует транзакционное поведение. Reflection обходит этот прокси и напрямую вызывает упакованный метод. Просмотр журналов должен подтвердить, что, возможно, вам придется набрать уровень журнала для весенних вещей.

Не используйте отражение для этого, потому что это идет за спиной Спринг, и это не может вам помочь. Вы можете автоматически связать список служб, которые реализуют общий интерфейс. Ваш код может go просмотреть список и выяснить, какой из них имеет отношение к тому, что вам нужно сделать, а затем вызвать метод для выбранной службы.

Если вы отправляете задачи исполнителю, вы собираетесь иметь проблемы, когда в рабочем потоке не найден менеджер сущностей. Если вы заставите эти службы использовать методы Spring asyn c, это позволит Spring обрабатывать транзакции, entityManager, et c.

...