Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Transactions 从事务性Kafka侦听器发送消息:尝试从\u事务中的状态转换到\u事务中的状态无效_Transactions_Apache Kafka_Spring Kafka - Fatal编程技术网

Transactions 从事务性Kafka侦听器发送消息:尝试从\u事务中的状态转换到\u事务中的状态无效

Transactions 从事务性Kafka侦听器发送消息:尝试从\u事务中的状态转换到\u事务中的状态无效,transactions,apache-kafka,spring-kafka,Transactions,Apache Kafka,Spring Kafka,我试图在同一事务中从Kafka listener发送消息,以便在同一事务中发送消息和提交偏移量,但收到一个异常:尝试从\u事务中的状态到\u事务中的状态的转换无效,并且该事务被回滚 我使用以下方法向我的应用程序(SpringBoot2、SpringKafka2.1.4)添加了事务支持 应用程序属性 spring.kafka.consumer.auto-offset-reset=earliest spring.kafka.consumer.enable-auto-commit=false spri

我试图在同一事务中从Kafka listener发送消息,以便在同一事务中发送消息和提交偏移量,但收到一个异常:尝试从\u事务中的状态到\u事务中的状态的转换无效,并且该事务被回滚

我使用以下方法向我的应用程序(SpringBoot2、SpringKafka2.1.4)添加了事务支持

应用程序属性

spring.kafka.consumer.auto-offset-reset=earliest
spring.kafka.consumer.enable-auto-commit=false
spring.kafka.consumer.group-id=transaction-sample
spring.kafka.listener.ack-mode=RECORD

spring.kafka.producer.transaction-id-prefix=transaction-sample-${random.uuid}
我已将kafkaTransactionManager设置为kafkaListenerContainerFactory containerProperties:

@SpringBootApplication
public class KafkaTransactionsSampleApplication {

  @Bean
  public ConcurrentKafkaListenerContainerFactory<?, ?> kafkaListenerContainerFactory(
      ConcurrentKafkaListenerContainerFactoryConfigurer configurer,
      ConsumerFactory<Object, Object> kafkaConsumerFactory,
      KafkaTransactionManager<Object, Object> kafkaTransactionManager) {
    ConcurrentKafkaListenerContainerFactory<Object, Object> factory = new ConcurrentKafkaListenerContainerFactory<>();
    configurer.configure(factory, kafkaConsumerFactory);
    factory.getContainerProperties().setTransactionManager(kafkaTransactionManager);
    return factory;
  }

  public static void main(String[] args) {
    SpringApplication.run(KafkaTransactionsSampleApplication.class, args);
  }
}
当我运行一个向输入主题发送消息的简单测试时,我收到一个异常:尝试从\u事务中的状态到\u事务中的状态的转换无效。然后事务回滚,消息不会转发到输出主题

@TestPropertySource("classpath:test.properties")
@RunWith(SpringRunner.class)
@SpringBootTest
public class KafkaListenerTest {

  @Autowired
  private KafkaEmbedded kafkaEmbedded;

  @Autowired
  private KafkaTemplate<String, String> kafkaTemplate;

  @Test
  public void shouldProcessEvent() throws Exception {
    String testKey = "test_key";
    String testData = "test_data";

    kafkaTemplate.send(INPUT_TEST_TOPIC, testKey, testData);

    try (Consumer<String, String> consumer = createConsumer()) {
      kafkaEmbedded.consumeFromAnEmbeddedTopic(consumer, OUTPUT_TEST_TOPIC);
      ConsumerRecords<String, String> records = KafkaTestUtils.getRecords(consumer);
      Iterator<ConsumerRecord<String, String>> iterator = records.iterator();
      ConsumerRecord<String, String> record = iterator.next();

      assertEquals(testKey, record.key());
      assertEquals(testData, record.value());
      assertFalse(iterator.hasNext());
    }
  }

  private Consumer<String, String> createConsumer() {
    Map<String, Object> consumerProps =
        KafkaTestUtils.consumerProps("test-consumer", "true", kafkaEmbedded);
    consumerProps.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
    DefaultKafkaConsumerFactory<String, String> cf = new DefaultKafkaConsumerFactory<>(
        consumerProps, new StringDeserializer(), new StringDeserializer());
    return cf.createConsumer();
  }
}

请不要在多个地方问同一个问题;它浪费了我们和你的时间

我已就您的GitHub问题回答了以下问题:

您的测试
send()
需要在自己的事务中运行:

kafkaTemplate.executeInTransaction(kt ->
    kt.send(INPUT_TEST_TOPIC, testKey, testData));
(或者不要使用事务模板)

我还修正了你的断言:

assertEquals(testKey, record.key());
assertEquals(testData, record.value());

(他们都在比较数值)。

谢谢。GitHub问题的链接:以后不会在多个地方问相同的问题,对此表示抱歉。拯救了我的一天。非常感谢。
2018-04-13 16:22:46.856 ERROR 141936 --- [ntainer#0-0-C-1] essageListenerContainer$ListenerConsumer : Transaction rolled back

org.springframework.transaction.CannotCreateTransactionException: Could not create Kafka transaction; nested exception is org.apache.kafka.common.KafkaException: TransactionalId transaction-sample-209b149f-7f97-42f6-82e7-257e1ac0d1950: Invalid transition attempted from state IN_TRANSACTION to state IN_TRANSACTION
    at org.springframework.kafka.transaction.KafkaTransactionManager.doBegin(KafkaTransactionManager.java:141) ~[spring-kafka-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:378) ~[spring-tx-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:137) ~[spring-tx-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.innvokeRecordListenerInTx(KafkaMessageListenerContainer.java:949) [spring-kafka-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeRecordListener(KafkaMessageListenerContainer.java:929) [spring-kafka-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeListener(KafkaMessageListenerContainer.java:801) [spring-kafka-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.run(KafkaMessageListenerContainer.java:689) [spring-kafka-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_144]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_144]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_144]
Caused by: org.apache.kafka.common.KafkaException: TransactionalId transaction-sample-209b149f-7f97-42f6-82e7-257e1ac0d1950: Invalid transition attempted from state IN_TRANSACTION to state IN_TRANSACTION
    at org.apache.kafka.clients.producer.internals.TransactionManager.transitionTo(TransactionManager.java:755) ~[kafka-clients-1.0.0.jar:na]
    at org.apache.kafka.clients.producer.internals.TransactionManager.transitionTo(TransactionManager.java:749) ~[kafka-clients-1.0.0.jar:na]
    at org.apache.kafka.clients.producer.internals.TransactionManager.beginTransaction(TransactionManager.java:215) ~[kafka-clients-1.0.0.jar:na]
    at org.apache.kafka.clients.producer.KafkaProducer.beginTransaction(KafkaProducer.java:564) ~[kafka-clients-1.0.0.jar:na]
    at org.springframework.kafka.core.DefaultKafkaProducerFactory$CloseSafeProducer.beginTransaction(DefaultKafkaProducerFactory.java:285) ~[spring-kafka-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.kafka.core.ProducerFactoryUtils.getTransactionalResourceHolder(ProducerFactoryUtils.java:60) ~[spring-kafka-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.kafka.transaction.KafkaTransactionManager.doBegin(KafkaTransactionManager.java:126) ~[spring-kafka-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    ... 9 common frames omitted
kafkaTemplate.executeInTransaction(kt ->
    kt.send(INPUT_TEST_TOPIC, testKey, testData));
assertEquals(testKey, record.key());
assertEquals(testData, record.value());