Production Patterns · Intermediate
Transactional Kafka Producer
Kafka transactions enable atomic writes across multiple topics/partitions. Required for exactly-once when combining multiple Kafka writes with a single business operation.
spring:
kafka:
producer:
transaction-id-prefix: order-service-tx-
# When transaction-id-prefix is set, Spring creates KafkaTransactionManager@Service
@Slf4j
public class TransactionalOrderService {
private final KafkaTemplate<String, Object> kafkaTemplate;
// Option 1: @Transactional (Spring coordinates Kafka + DB transaction)
@Transactional("kafkaTransactionManager")
public void processOrderWithEvents(Order order) {
// Both sends are atomic — either both commit or both abort
kafkaTemplate.send("orders.order.created",
order.getId(), new OrderCreatedEvent(order));
kafkaTemplate.send("inventory.reservation.requested",
order.getId(), new ReservationRequest(order));
// If exception thrown here, both messages are ABORTED
}
// Option 2: Explicit transaction control
public void processWithExplicitTx(Order order) {
kafkaTemplate.executeInTransaction(operations -> {
operations.send("orders.order.created", order.getId(), new OrderCreatedEvent(order));
operations.send("payments.payment.requested", order.getId(), new PaymentRequest(order));
return true;
});
}
// Option 3: Chained Kafka + DB transaction (consume-transform-produce)
@Transactional("chainedKafkaTransactionManager")
@KafkaListener(topics = "orders.order.created")
public void consumeAndProduce(OrderCreatedEvent event) {
// Save to DB + produce output event are atomic
orderRepository.save(new Order(event));
kafkaTemplate.send("orders.order.processed", event.getOrderId(), new ProcessedEvent(event));
}
}