我正在使用带有 KafkaTransactionManager 和 DefaultErrorHandler 的 Spring Kafka 3.0.5。
在我的消费者配置中:
确认模式设置为 BATCH
监听器类型为@KafkaListener(基于记录)
事务已启用(KafkaTransactionManager)
重试配置为 DefaultErrorHandler.setRetryListeners(...) 和 10 次重试
在对一批消息进行测试时,我观察到了以下情况:
如果轮询批次中的最后一条记录失败,则整个事务将回滚,并且偏移量不会提交 - 正如预期的那样。
如果最后一条记录成功,即使批次中的先前记录失败但重试成功,整个事务也会提交,并且消费者滞后变为 0。
这意味着批次中最后一条记录的最终结果似乎决定了事务是否被提交。
问题:
这是预期的行为吗——最后一条记录的结果决定了事务提交?
这在 Spring Kafka 或 Kafka 自己的事务行为中是否有记录?
有没有办法让每个记录的事务提交更加明确,或者将其与最终记录状态分离?
如能提供任何说明或文档链接,我们将不胜感激。
我找到了答案。
当使用Kafka事务时,确认模式(AckMode)实际上并不影响行为。
请参阅此讨论以供参考:
Spring Kafka Consumer ACKMODE 和 Producer 缓冲 Kafka 事务
即使在 TransactionTemplate 中,它也只是执行代码然后提交——没有与 AckMode 的协调。
因此,无论您设置的是 AckMode.BATCH 还是 AckMode.RECORD,事务边界决定了提交,而不是确认模式。https
://github.com/spring-projects/spring-framework/blob/39e263fe5d8ba767d22e594cffd02420bab43f2a/spring-tx/src/main/java/org/springframework/transaction/support/TransactionTemplate.java#L127