I'm trying to publish messages to Kafka from a transaction using KafkaTemplate:
@Autowired
KafkaTemplate<GenericRecord, GenericRecord> kafkaTemplate;
@Transactional
@RabbitListener(queues = "queueName")
void input(final List<Message> messages) {
for (Message msg : messages) {
PublishRequest request = prepareRequest(msg);
kafkaTemplate.sendDefault(request.getKey(), reguest.getValue());
}
transactionalDatabaseInserts();
}
But when I do it I'm getting this exception:
Caused by: java.lang.IllegalStateException: No transaction is in process; possible solutions: run the template operation within the scope of a template.executeInTransaction() operation, start a transaction with @Transactional before invoking the template method, run in a transaction started by a listener container when consuming a record
Configs for KafkaTemplate:
@EnableTransactionManagement
@Configuration
public class KafkaConfig{
@Bean
KafkaTransactionManager<GenericRecord, GenericRecord> kafkaTransactionManager(final ProducerFactory<GenericRecord, GenericRecord> producerFactory) {
return new KafkaTransactionManager<>(producerFactory);
}
@Bean
KafkaTemplate<GenericRecord, GenericRecord> kafkaTemplate(final ProducerFactory<GenericRecord, GenericRecord> producerFactory) {
return new KafkaTemplate<>(producerFactory);
}
}
In my application.yaml I have included:
spring.kafka.producer.transaction-id-prefix: tx-
I want my method to work with @Transactional and not kafkaTemplate.executeInTransaction(). Why am I getting that exception?