You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Kafka嵌套单元测试触发ProducerFencedException问题排查与解决

Spring-Kafka-Test 3.0.6 嵌套测试触发ProducerFencedException的解决方案

问题场景

使用spring-kafka-test 3.0.6进行单元测试时,包含两个嵌套测试用例Test1和Test2(Test1先执行,Test2后执行),每次测试几乎都会触发ProducerFencedException。

测试代码示例

@Test
@Nested
inner class Test1 {
   fun test1() {
     mypublisher.publishInTransaction(topic1)  // see log1
     // check listener1  // see log2
   }
}

@Test
@Nested
inner class Test2 {
   fun test2() {
     mypublisher.publishInTransaction(topic2)  // see log3
     // check listener2
   }
}

fun MyPublisher.publishInTransaction(topic: String) {
  // producerOnlyKafkaTemplate是KafkaTemplate实例
  producerOnlyKafkaTemplate.executeInTransaction {
    producerOnlyKafkaTemplate.send(topic, "test-message")
  }
}

问题原因分析

从日志中可以观察到:

  • Test1中创建的Producer(如Producer@58bb6ba7)提交事务后被关闭
  • Test2复用该Producer时,提交事务触发ProducerFencedException

进一步排查发现,本应是单例的MyProducerOnlyFactory Bean被初始化了两次,导致同一个transactionalId关联了两个ProducerFactory实例:

  1. MyProducerOnlyFactory-1创建的Producer提交事务后被放回缓存
  2. MyProducerOnlyFactory-2复用该Producer并将其producerEpoch更新为1
  3. 后续MyProducerOnlyFactory-1再次获取该Producer时,仍认为其epoch为0,提交事务时因epoch不匹配触发异常

解决方案

在测试类上添加@NestedTestConfiguration(NestedTestConfiguration.EnclosingConfiguration.OVERRIDE)注解,确保MyProducerOnlyFactory Bean仅被初始化一次:

@NestedTestConfiguration(NestedTestConfiguration.EnclosingConfiguration.OVERRIDE)
class YourTestClass {
    // 嵌套测试用例Test1、Test2
}

内容的提问来源于stack exchange,提问作者jon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 12:52:43