【问题标题】:TransactionalEventListener ignored if event is published from another listener如果事件是从另一个侦听器发布的,则忽略 TransactionalEventListener
【发布时间】:2018-11-11 22:53:47
【问题描述】:

我有一个服务和两个具有 BEFORE_COMMIT 阶段的 TransactionalEventListener,一个监听 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);
    }
}

服务方法执行后,数据库中有两行——“entity”和“entityA”。
替代 EventAListener 版本的工作方式相同。
将 EventBListener fallbackExecution 设置为 'true' 不会进行任何更改 - 不会调用 EventBListener。
将 EventBListener 阶段更改为 AFTER_COMMIT 有效 - EventB 已处理,但在另一个事务中。

为什么 EventB 没有被处理?

【问题讨论】:

    标签: java spring spring-data-jpa spring-transactions


    【解决方案1】:

    我认为您的问题可能与 Wojtek 在此处发布的问题有关: https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2

    Spring 开发者回答如下:

    BEFORE_COMMIT 不是“在交易期间的任何时候”。 真的 在提交之前。您正在做的是使用事务,就像没有要求提交一样。发生了什么事。

    因此,BEFORE_COMMIT 事件的链接似乎是不可能的,并且可能不支持在该阶段执行另一个事务操作(即使它看起来有效)?

    我认为这个领域可以更好地记录,因为对于大多数人来说,“提交之前”只是意味着“在提交某事之前”,并且在调用该事件处理程序时可以执行哪些操作并不是很清楚。

    【讨论】:

    • 谢谢你,我尝试了很多不同的东西
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    • 2014-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    相关资源
    最近更新 更多