@@ -379,7 +379,7 @@ private TransactionalRequestResult beginCompletingTransaction(TransactionResult
379
379
380
380
EndTxnHandler handler = new EndTxnHandler (builder );
381
381
enqueueRequest (handler );
382
- if (!shouldBumpEpoch () ) {
382
+ if (!epochBumpRequired ) {
383
383
return handler .result ;
384
384
}
385
385
}
@@ -553,10 +553,6 @@ synchronized void requestEpochBumpForPartition(TopicPartition tp) {
553
553
this .partitionsToRewriteSequences .add (tp );
554
554
}
555
555
556
- private boolean shouldBumpEpoch () {
557
- return epochBumpRequired ;
558
- }
559
-
560
556
private void bumpIdempotentProducerEpoch () {
561
557
if (this .producerIdAndEpoch .epoch == Short .MAX_VALUE ) {
562
558
resetIdempotentProducerId ();
@@ -577,7 +573,7 @@ private void bumpIdempotentProducerEpoch() {
577
573
578
574
synchronized void bumpIdempotentEpochAndResetIdIfNeeded () {
579
575
if (!isTransactional ()) {
580
- if (shouldBumpEpoch () ) {
576
+ if (epochBumpRequired ) {
581
577
bumpIdempotentProducerEpoch ();
582
578
}
583
579
if (currentState != State .INITIALIZING && !hasProducerId ()) {
@@ -1014,10 +1010,14 @@ synchronized boolean canRetry(ProduceResponse.PartitionResponse response, Produc
1014
1010
1015
1011
if (!isTransactional ()) {
1016
1012
// For the idempotent producer, always retry UNKNOWN_PRODUCER_ID errors. If the batch has the current
1017
- // producer ID and epoch, request a bump of the epoch. Otherwise just retry, as the
1013
+ // producer ID and epoch, request a bump of the epoch. Otherwise just retry the produce.
1018
1014
requestEpochBumpForPartition (batch .topicPartition );
1019
1015
return true ;
1020
1016
}
1017
+ } else if (error == Errors .INVALID_PRODUCER_EPOCH ) {
1018
+ // Retry the initProducerId to bump the epoch and continue.
1019
+ requestEpochBumpForPartition (batch .topicPartition );
1020
+ return true ;
1021
1021
} else if (error == Errors .OUT_OF_ORDER_SEQUENCE_NUMBER ) {
1022
1022
if (!hasUnresolvedSequence (batch .topicPartition ) &&
1023
1023
(batch .sequenceHasBeenReset () || !isNextSequence (batch .topicPartition , batch .baseSequence ()))) {
@@ -1366,6 +1366,10 @@ public void handleResponse(AbstractResponse response) {
1366
1366
} else if (error == Errors .TRANSACTIONAL_ID_AUTHORIZATION_FAILED ||
1367
1367
error == Errors .CLUSTER_AUTHORIZATION_FAILED ) {
1368
1368
fatalError (error .exception ());
1369
+ } else if (error == Errors .INVALID_PRODUCER_EPOCH || error == Errors .PRODUCER_FENCED ) {
1370
+ // We could still receive INVALID_PRODUCER_EPOCH from old versioned transaction coordinator,
1371
+ // just treat it the same as PRODUCE_FENCED.
1372
+ fatalError (Errors .PRODUCER_FENCED .exception ());
1369
1373
} else {
1370
1374
fatalError (new KafkaException ("Unexpected error in InitProducerIdResponse; " + error .message ()));
1371
1375
}
@@ -1417,8 +1421,10 @@ public void handleResponse(AbstractResponse response) {
1417
1421
} else if (error == Errors .COORDINATOR_LOAD_IN_PROGRESS || error == Errors .UNKNOWN_TOPIC_OR_PARTITION ) {
1418
1422
reenqueue ();
1419
1423
return ;
1420
- } else if (error == Errors .INVALID_PRODUCER_EPOCH ) {
1421
- fatalError (error .exception ());
1424
+ } else if (error == Errors .INVALID_PRODUCER_EPOCH || error == Errors .PRODUCER_FENCED ) {
1425
+ // We could still receive INVALID_PRODUCER_EPOCH from old versioned transaction coordinator,
1426
+ // just treat it the same as PRODUCE_FENCED.
1427
+ fatalError (Errors .PRODUCER_FENCED .exception ());
1422
1428
return ;
1423
1429
} else if (error == Errors .TRANSACTIONAL_ID_AUTHORIZATION_FAILED ) {
1424
1430
fatalError (error .exception ());
@@ -1575,8 +1581,10 @@ public void handleResponse(AbstractResponse response) {
1575
1581
reenqueue ();
1576
1582
} else if (error == Errors .COORDINATOR_LOAD_IN_PROGRESS || error == Errors .CONCURRENT_TRANSACTIONS ) {
1577
1583
reenqueue ();
1578
- } else if (error == Errors .INVALID_PRODUCER_EPOCH ) {
1579
- fatalError (error .exception ());
1584
+ } else if (error == Errors .INVALID_PRODUCER_EPOCH || error == Errors .PRODUCER_FENCED ) {
1585
+ // We could still receive INVALID_PRODUCER_EPOCH from old versioned transaction coordinator,
1586
+ // just treat it the same as PRODUCE_FENCED.
1587
+ fatalError (Errors .PRODUCER_FENCED .exception ());
1580
1588
} else if (error == Errors .TRANSACTIONAL_ID_AUTHORIZATION_FAILED ) {
1581
1589
fatalError (error .exception ());
1582
1590
} else if (error == Errors .INVALID_TXN_STATE ) {
@@ -1632,8 +1640,10 @@ public void handleResponse(AbstractResponse response) {
1632
1640
reenqueue ();
1633
1641
} else if (error == Errors .UNKNOWN_PRODUCER_ID || error == Errors .INVALID_PRODUCER_ID_MAPPING ) {
1634
1642
abortableErrorIfPossible (error .exception ());
1635
- } else if (error == Errors .INVALID_PRODUCER_EPOCH ) {
1636
- fatalError (error .exception ());
1643
+ } else if (error == Errors .INVALID_PRODUCER_EPOCH || error == Errors .PRODUCER_FENCED ) {
1644
+ // We could still receive INVALID_PRODUCER_EPOCH from old versioned transaction coordinator,
1645
+ // just treat it the same as PRODUCE_FENCED.
1646
+ fatalError (Errors .PRODUCER_FENCED .exception ());
1637
1647
} else if (error == Errors .TRANSACTIONAL_ID_AUTHORIZATION_FAILED ) {
1638
1648
fatalError (error .exception ());
1639
1649
} else if (error == Errors .GROUP_AUTHORIZATION_FAILED ) {
0 commit comments