【问题标题】:Fully Transactional Spring Kafka Consumer/Listener完全事务性的 Spring Kafka 消费者/侦听器
【发布时间】:2021-10-27 23:00:11
【问题描述】:

目前,我有一个配置了 ConcurrentKafkaListenerContainerFactorySeekToCurrentErrorHandler 的 Kafka 侦听器(DeadLetterPublishingRecoverer 配置了 1 次重试)。 我的 Listener 方法用 @Transactional 注释(以及我的服务中与数据库交互的所有方法)。

我的 Listener 方法执行以下操作:

  1. 从 Kafka 接收消息
  2. 与多个服务交互,将接收到的数据的不同部分保存到数据库中
  3. Kafka 中的确认消息(即提交偏移量)

如果它在中间的某个地方失败,它应该回滚并重试,直到最大重试次数。 然后向 DLT 发送消息。

我正在尝试使此方法完全具有事务性,即,如果出现故障,所有以前的更改都会回滚。 但是,Listener 方法中的@Transactional 注解是不够的。 我怎样才能做到这一点? 我应该采用哪些配置来使 Listener 方法完全事务化?

【问题讨论】:

    标签: apache-kafka spring-kafka


    【解决方案1】:

    如果您还没有从侦听器发布到 Kafka,则没有必要(或好处)使用 Kafka 事务;只是开销。 STCEH + DLPR 就足够了。

    如果您还发布到 Kafka(并且希望这些也回滚),请参阅 the documentation - 在侦听器容器中配置 KafkaTransactionManager。

    【讨论】:

    • 我没有在这个特定的监听器中发布到 Kafka。但是,我正在与写入数据库的不同服务(在本例中为 3 个服务)进行交互。如果由于某种原因,在第一次服务交互后抛出异常,则该服务写入的数据不会被回滚。我怎样才能做到这一点?
    • 监听器上的 @Transactional 应该完全做到这一点(除非您在每个服务上都有传播 REQUIRES_NEW,这将为每个服务启动一个新事务)。使用包含整个事务的侦听器,它应该按预期工作(但您必须从侦听器中引发异常才能发生)。 o.s.transaction 的调试/跟踪日志记录应该可以帮助您进行调试。这个问题真的和Kafka没有关系,是基本的Spring事务管理。
    • 好的,感谢您的帮助。我将尝试调试问题。这种情况下offset commit还是DLPR也是事务性执行的?
    • 在 DLPR 中发布单个记录时,使用事务没有任何好处,只有开销;但是,如果您愿意,只需使用事务模板配置 DLPR。
    • 好的。但是关于偏移量的提交,它是事务性执行的吗?也就是如果在offset的提交过程中出了问题,剩下的事务会回滚吗?
    猜你喜欢
    • 2019-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-08
    • 2020-11-06
    • 1970-01-01
    • 2018-02-08
    • 2019-01-15
    相关资源
    最近更新 更多