TransactionalEventListener игнорируется, если событие опубликовано от другого слушателя - PullRequest
0 голосов
/ 01 июня 2018

У меня есть служба и два TransactionalEventListeners с фазой BEFORE_COMMIT, один прослушивает EventA, другой - EventB.Сервис публикует EventA -> EventAListener вызывается и публикует другое событие - EventB.EventBListener не вызывается, и событие игнорируется.Пример кода:

@Service
@Transactional
public class ExampleService {
    private ExampleEntityRepository repository;
    private ApplicationEventPublisher applicationEventPublisher;

    public void exampleMethod() {
        repository.save(new ExampleEntity("entity"));
        applicationEventPublisher.publishEvent(new EventA(this));
    }
}

//==================================================

@Service
@Transactional
public class EventAListener {
    private ExampleEntityRepository repository;
    private ApplicationEventPublisher applicationEventPublisher;

    @TransactionalEventListener(value = EventA.class, phase = TransactionPhase.BEFORE_COMMIT)
    public void handle(EventA event) {
        repository.save(new ExampleEntity("entityA"));
        applicationEventPublisher.publishEvent(new EventB(this));
    }
}

//==================================================

@Service
@Transactional
public class EventBListener {
    private ExampleEntityRepository repository;

    @TransactionalEventListener(value = EventB.class, phase = TransactionPhase.BEFORE_COMMIT)
    public void handle(EventB eventB) {
        repository.save(new ExampleEntity("entityB"));
    }
}

//==================================================

// Alternative EventAListener version
@Service
@Transactional
public class EventAListener {
    private ExampleEntityRepository repository;

    @TransactionalEventListener(value = EventA.class, phase = TransactionPhase.BEFORE_COMMIT)
    public EventB handle(EventA event) {
        repository.save(new ExampleEntity("entityA"));
        return new EventB(this);
    }
}

После выполнения служебного метода в базе данных есть 2 строки - «entity» и «entityA».Альтернативная версия EventAListener работает так же.Установка EventBListener fallbackExecution в 'true' не вносит никаких изменений - EventBListener не вызываетсяИзменение фазы EventBListener на AFTER_COMMIT работает - EventB обрабатывается, но в другой транзакции.

Почему EventB не обрабатывается?

1 Ответ

0 голосов
/ 09 июля 2018

Я думаю, что ваша проблема может быть связана с той, которую написал Wojtek здесь: https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2

На что разработчик Spring отвечает следующим образом:

BEFORE_COMMIT не«в любое время во время транзакции».Это действительно до коммита.То, что вы делаете, использует транзакцию, как будто ничего не запрашивалось для фиксации.Что-то сделало.

Так что кажется, что цепочка событий BEFORE_COMMIT невозможна, и, возможно, выполнение другой транзакционной операции на этом этапе не поддерживается (даже если кажется, что она работает)?

Я думаю, что эта область могла бы быть лучше задокументирована, потому что для большинства людей «до коммита» просто означает «до того, как что-то было зафиксировано», и не совсем понятно, какие операции можно выполнить при вызове этого обработчика событий.

...