I\'ve read many articles where there are many different configurations to achieve exactly once processing.
Here is my producer config:
final Map
See the javadocs for receiveExactlyOnce
/**
* Returns a {@link Flux} of consumer record batches that may be used for exactly once
* delivery semantics. A new transaction is started for each inner Flux and it is the
* responsibility of the consuming application to commit or abort the transaction
* using {@link TransactionManager#commit()} or {@link TransactionManager#abort()}
* after processing the Flux.
begin()
has already been called so you don't need to call it.
@Override
public Flux<Flux<ConsumerRecord<K, V>>> receiveExactlyOnce(TransactionManager transactionManager) {
this.ackMode = AckMode.EXACTLY_ONCE;
Flux<ConsumerRecords<K, V>> flux = withDoOnRequest(createConsumerFlux());
return flux.map(consumerRecords -> transactionManager.begin()
.then(Mono.fromCallable(() -> awaitingTransaction.getAndSet(true)))
.thenMany(transactionalRecords(transactionManager, consumerRecords)))
.publishOn(transactionManager.scheduler());
}