如果事件是从另一个侦听器发布的,则忽略事务事件侦听器



我有一个服务和两个阶段为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 行 - "实体"和"实体 A"。
替代事件AListener版本的工作方式相同。
将 EventBListener fallbackExecution 设置为 'true' 不会进行任何更改 - 不会调用 EventBListener。
将 EventBListener 阶段更改为 AFTER_COMMIT 工作 - 处理 EventB,但在另一个事务中。

为什么不处理事件 B?

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

Spring开发人员的回答如下:

BEFORE_COMMIT不是"在交易过程中随时"。这真的是在提交之前。您正在做的是使用事务,就像没有要求提交一样。有些事情发生了。

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

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

最新更新