Estou usando o Spring Kafka 3.0.5 com o KafkaTransactionManager e o DefaultErrorHandler.
Na minha configuração de consumidor:
O modo de confirmação está definido como LOTE
O tipo de ouvinte é @KafkaListener (baseado em registro)
As transações estão habilitadas (KafkaTransactionManager)
A nova tentativa é configurada com DefaultErrorHandler.setRetryListeners(...) e 10 novas tentativas
Ao testar com um lote de mensagens, observei o seguinte:
Se o último registro em um lote pesquisado falhar, toda a transação será revertida e o deslocamento não será confirmado — como esperado.
Se o último registro for bem-sucedido, mesmo que os registros anteriores no lote tenham falhado, mas tentado novamente com sucesso, a transação inteira será confirmada e o atraso do consumidor se tornará 0.
Isso significa que o resultado final do último registro no lote parece determinar se a transação foi confirmada ou não.
Questões:
Esse comportamento é esperado — que o resultado do último registro decida a confirmação da transação?
Isso está documentado em algum lugar no Spring Kafka ou no próprio comportamento transacional do Kafka?
Existe uma maneira de tornar a confirmação da transação mais explícita por registro ou dissociá-la do status final do registro?
Qualquer esclarecimento ou links de documentação seriam muito apreciados.
Eu encontrei a resposta.
Ao usar transações do Kafka, o modo de reconhecimento (AckMode) não afeta o comportamento.
Veja esta discussão para referência:
Spring Kafka Consumer ACKMODE e buffer de produtor para transações Kafka
Mesmo no TransactionTemplate, ele simplesmente executa o código e então confirma — não há coordenação com o AckMode.
Portanto, independentemente de você definir AckMode.BATCH ou AckMode.RECORD, o limite da transação determina a confirmação, não o modo de reconhecimento.
https://github.com/spring-projects/spring-framework/blob/39e263fe5d8ba767d22e594cffd02420bab43f2a/spring-tx/src/main/java/org/springframework/transaction/support/TransactionTemplate.java#L127