Transaction-bound Events

从 Spring 4.2 开始,事件的监听器可以绑定到事务的一个阶段。一个典型的例子是在事务成功完成时处理事件。这样做可以让事件在当前事务的结果确实对监听器很重要时更加灵活地使用。

你可以使用 @EventListener 注释来注册常规事件监听器。如果你需要将其绑定到事务,请使用 @TransactionalEventListener。当你这样做时,监听器默认绑定到事务的提交阶段。

下一个示例展示了这个概念。假设某个组件发布了一个 order-created 事件,并且我们想要定义一个监听器,它只在发布它的事务成功提交后才处理该事件。以下示例设置了一个这样的事件监听器:

  • Java

  • Kotlin

@Component
public class MyComponent {

	@TransactionalEventListener
	public void handleOrderCreatedEvent(CreationEvent<Order> creationEvent) {
		// ...
	}
}
@Component
class MyComponent {

	@TransactionalEventListener
	fun handleOrderCreatedEvent(creationEvent: CreationEvent<Order>) {
		// ...
	}
}

@TransactionalEventListener 注释公开了一个 phase 属性,允许你自定义监听器应该绑定的事务阶段。有效阶段有 BEFORE_COMMITAFTER_COMMIT(默认)、AFTER_ROLLBACK 以及 AFTER_COMPLETION,它汇总了事务完成(无论它是提交还是回滚)。

如果没有事务正在运行,那么根本不会调用该监听器,因为我们无法尊重必需的语义。但是,你可以通过将注释的 fallbackExecution 属性设置为 true 来覆盖该行为。

从 6.1 开始,@TransactionalEventListener 可以与由 PlatformTransactionManager 管理的线程绑定事务以及由 ReactiveTransactionManager 管理的反应式事务一起使用。对于前者,监听器一定会看到当前的线程绑定事务。由于后者使用 Reactor 上下文而不是线程局部变量,因此事务上下文需要作为事件源包含在发布的事件实例中。有关详细信息,请参阅https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/reactive/TransactionalEventPublisher.html[TransactionalEventPublisher] javadoc。