[英]How to use @Transactional with @KafkaListener?
是否有可能将声明性 tx 管理(通过 @Transactional)与 @KafkaListener 注释方法一起使用? 例如,我想使用它来为每个侦听器定义单独的 tx 超时。 我的设置如下:
事务管理器:
@Bean
@ConditionalOnBean(value = {HibernateTransactionManager.class})
public ChainedKafkaTransactionManager<Object, Object> chainedHibernateTm(KafkaTransactionManager<String, String> kafkaTransactionManager,
org.springframework.orm.hibernate5.HibernateTransactionManager hibernateTransactionManager) {
return new ChainedKafkaTransactionManager<>(kafkaTransactionManager, hibernateTransactionManager);
}
卡夫卡监听器:
@KafkaListener(topic = "my_topic")
@Transactional(timeout = 5)
public void handleMessage(SomeMessage message){
}
问题是 - KafkaMessageListenerContainer 在调用此类方法之前创建自己的事务 - 它使用自己的 TransactionTemplate:
@Nullable
private TransactionTemplate determineTransactionTemplate() {
return this.transactionManager != null
? new TransactionTemplate(this.transactionManager)
: null;
}
不使用 TransactionInterceptor。 那么如何为具体的@KafkaListener 方法设置特定的 tx 超时呢?
可以做到,但有点复杂,因为您必须将消耗的偏移量发送到 Kafka 事务。
您可以将KafkaTransactionManager
用于容器,将@Transactional
用于HibernateTransactionManager
,而不是使用ChainedKafkaTransactionManager
。
这将给出类似的结果,因为 hibernate TX 将在 Kafka 事务之前提交(如果 hibernate 提交失败,Kafka TX 将回滚)。
编辑
要将不同的链式 TM 配置到每个侦听器容器中,您可以执行以下操作。
@Component class ContainerFactoryCustomizer {
ContainerFactoryCustomizer(AbstractKafkaListenerContainerFactory<?, ?, ?> factory,
ChainedKafkaTransactionManager<?, ?> chainedOne,
ChainedKafkaTransactionManager<?, ?> chainedTwo) {
factory.setContainerCustomizer(
container -> {
String groupId = container.getContainerProperties().getGroupId();
if (groupId.equals("foo")) {
container.getContainerProperties().setTransactionManager(chainedOne);
}
else {
container.getContainerProperties().setTransactionManager(chainedTwo);
}
});
}
}
Where each chained TM has a Hibernate TM with a different default timeout.
The `groupid` is populated from the `@KafkaListener` `id` or `groupId` property.
通过普通的@Transactional
进行事务管理的方面并不像您想要的那样与 Kafka 侦听器一起工作 - 没有内置的交互。
有一个专门的章节如何在事务中使用应用程序事件:使用注释@TransactionalEventListener
的事务绑定事件有助于确保事务已成功完成。
您可以使用 @EventListener 注释注册常规事件侦听器。 如果需要将其绑定到事务,请使用@TransactionalEventListener。 当您这样做时,默认情况下侦听器绑定到事务的提交阶段。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.