76
76
import org .springframework .kafka .KafkaException ;
77
77
import org .springframework .kafka .core .ConsumerFactory ;
78
78
import org .springframework .kafka .core .KafkaResourceHolder ;
79
- import org .springframework .kafka .core .ProducerFactory ;
80
79
import org .springframework .kafka .event .ConsumerFailedToStartEvent ;
81
80
import org .springframework .kafka .event .ConsumerPartitionPausedEvent ;
82
81
import org .springframework .kafka .event .ConsumerPartitionResumedEvent ;
102
101
import org .springframework .kafka .support .LogIfLevelEnabled ;
103
102
import org .springframework .kafka .support .TopicPartitionOffset ;
104
103
import org .springframework .kafka .support .TopicPartitionOffset .SeekPosition ;
105
- import org .springframework .kafka .support .TransactionSupport ;
106
104
import org .springframework .kafka .support .micrometer .MicrometerHolder ;
107
105
import org .springframework .kafka .support .serializer .DeserializationException ;
108
106
import org .springframework .kafka .support .serializer .ErrorHandlingDeserializer ;
@@ -738,8 +736,6 @@ private final class ListenerConsumer implements SchedulingAwareRunnable, Consume
738
736
739
737
private Producer <?, ?> producer ;
740
738
741
- private boolean producerPerConsumerPartition ;
742
-
743
739
private boolean commitRecovered ;
744
740
745
741
private boolean wasIdle ;
@@ -1022,10 +1018,6 @@ boolean isPartitionPaused(TopicPartition topicPartition) {
1022
1018
1023
1019
@ Nullable
1024
1020
private TransactionTemplate determineTransactionTemplate () {
1025
- if (this .kafkaTxManager != null ) {
1026
- this .producerPerConsumerPartition =
1027
- this .kafkaTxManager .getProducerFactory ().isProducerPerConsumerPartition ();
1028
- }
1029
1021
if (this .transactionManager != null ) {
1030
1022
TransactionTemplate template = new TransactionTemplate (this .transactionManager );
1031
1023
TransactionDefinition definition = this .containerProperties .getTransactionDefinition ();
@@ -1740,9 +1732,6 @@ private void wrapUp(@Nullable Throwable throwable) {
1740
1732
// No-op. Continue process
1741
1733
}
1742
1734
}
1743
- else {
1744
- closeProducers (partitions );
1745
- }
1746
1735
}
1747
1736
else {
1748
1737
this .logger .error ("Fatal consumer exception; stopping container" );
@@ -1995,11 +1984,6 @@ private void invokeBatchListenerInTx(final ConsumerRecords<K, V> records,
1995
1984
@ Nullable final List <ConsumerRecord <K , V >> recordList ) {
1996
1985
1997
1986
try {
1998
- if (this .subBatchPerPartition && this .producerPerConsumerPartition ) {
1999
- ConsumerRecord <K , V > record = recordList == null ? records .iterator ().next () : recordList .get (0 );
2000
- TransactionSupport
2001
- .setTransactionIdSuffix (zombieFenceTxIdSuffix (record .topic (), record .partition ())); // NOSONAR
2002
- }
2003
1987
this .transactionTemplate .execute (new TransactionCallbackWithoutResult () {
2004
1988
2005
1989
@ Override
@@ -2028,11 +2012,6 @@ public void doInTransactionWithoutResult(TransactionStatus s) {
2028
2012
this .logger .error (e , "Transaction rolled back" );
2029
2013
batchRollback (records , recordList , e );
2030
2014
}
2031
- finally {
2032
- if (this .subBatchPerPartition && this .producerPerConsumerPartition ) {
2033
- TransactionSupport .clearTransactionIdSuffix ();
2034
- }
2035
- }
2036
2015
}
2037
2016
2038
2017
private void batchRollback (final ConsumerRecords <K , V > records ,
@@ -2327,11 +2306,6 @@ private void invokeRecordListenerInTx(final ConsumerRecords<K, V> records) {
2327
2306
this .logger .error (ex , "Transaction rolled back" );
2328
2307
recordAfterRollback (iterator , record , ex );
2329
2308
}
2330
- finally {
2331
- if (this .producerPerConsumerPartition ) {
2332
- TransactionSupport .clearTransactionIdSuffix ();
2333
- }
2334
- }
2335
2309
if (this .commonRecordInterceptor != null ) {
2336
2310
this .commonRecordInterceptor .afterRecord (record , this .consumer );
2337
2311
}
@@ -2344,10 +2318,6 @@ private void invokeRecordListenerInTx(final ConsumerRecords<K, V> records) {
2344
2318
}
2345
2319
2346
2320
private void invokeInTransaction (Iterator <ConsumerRecord <K , V >> iterator , final ConsumerRecord <K , V > record ) {
2347
- if (this .producerPerConsumerPartition ) {
2348
- TransactionSupport
2349
- .setTransactionIdSuffix (zombieFenceTxIdSuffix (record .topic (), record .partition ()));
2350
- }
2351
2321
this .transactionTemplate .execute (new TransactionCallbackWithoutResult () {
2352
2322
2353
2323
@ Override
@@ -3109,25 +3079,6 @@ public String toString() {
3109
3079
+ "\n ]" ;
3110
3080
}
3111
3081
3112
- private void closeProducers (@ Nullable Collection <TopicPartition > partitions ) {
3113
- if (partitions != null ) {
3114
- ProducerFactory <?, ?> producerFactory = this .kafkaTxManager .getProducerFactory ();
3115
- partitions .forEach (tp -> {
3116
- try {
3117
- producerFactory .closeProducerFor (zombieFenceTxIdSuffix (tp .topic (), tp .partition ()));
3118
- }
3119
- catch (Exception e ) {
3120
- this .logger .error (e , () -> "Failed to close producer with transaction id suffix: "
3121
- + zombieFenceTxIdSuffix (tp .topic (), tp .partition ()));
3122
- }
3123
- });
3124
- }
3125
- }
3126
-
3127
- private String zombieFenceTxIdSuffix (String topic , int partition ) {
3128
- return this .consumerGroupId + "." + topic + "." + partition ;
3129
- }
3130
-
3131
3082
private final class ConsumerAcknowledgment implements Acknowledgment {
3132
3083
3133
3084
private final ConsumerRecord <K , V > record ;
@@ -3246,47 +3197,40 @@ private class ListenerConsumerRebalanceListener implements ConsumerRebalanceList
3246
3197
3247
3198
@ Override
3248
3199
public void onPartitionsRevoked (Collection <TopicPartition > partitions ) {
3200
+ if (this .consumerAwareListener != null ) {
3201
+ this .consumerAwareListener .onPartitionsRevokedBeforeCommit (ListenerConsumer .this .consumer ,
3202
+ partitions );
3203
+ }
3204
+ else {
3205
+ this .userListener .onPartitionsRevoked (partitions );
3206
+ }
3249
3207
try {
3250
- if (this .consumerAwareListener != null ) {
3251
- this .consumerAwareListener .onPartitionsRevokedBeforeCommit (ListenerConsumer .this .consumer ,
3252
- partitions );
3253
- }
3254
- else {
3255
- this .userListener .onPartitionsRevoked (partitions );
3256
- }
3257
- try {
3258
- // Wait until now to commit, in case the user listener added acks
3259
- commitPendingAcks ();
3260
- fixTxOffsetsIfNeeded ();
3261
- }
3262
- catch (Exception e ) {
3263
- ListenerConsumer .this .logger .error (e , () -> "Fatal commit error after revocation "
3264
- + partitions );
3265
- }
3266
- if (this .consumerAwareListener != null ) {
3267
- this .consumerAwareListener .onPartitionsRevokedAfterCommit (ListenerConsumer .this .consumer ,
3268
- partitions );
3269
- }
3270
- if (ListenerConsumer .this .consumerSeekAwareListener != null ) {
3271
- ListenerConsumer .this .consumerSeekAwareListener .onPartitionsRevoked (partitions );
3272
- }
3273
- if (ListenerConsumer .this .assignedPartitions != null ) {
3274
- ListenerConsumer .this .assignedPartitions .removeAll (partitions );
3275
- }
3276
- ListenerConsumer .this .pausedForNack .removeAll (partitions );
3277
- partitions .forEach (tp -> ListenerConsumer .this .lastCommits .remove (tp ));
3278
- synchronized (ListenerConsumer .this ) {
3279
- if (ListenerConsumer .this .offsetsInThisBatch != null ) {
3280
- partitions .forEach (tp -> {
3281
- ListenerConsumer .this .offsetsInThisBatch .remove (tp );
3282
- ListenerConsumer .this .deferredOffsets .remove (tp );
3283
- });
3284
- }
3285
- }
3208
+ // Wait until now to commit, in case the user listener added acks
3209
+ commitPendingAcks ();
3210
+ fixTxOffsetsIfNeeded ();
3286
3211
}
3287
- finally {
3288
- if (ListenerConsumer .this .kafkaTxManager != null ) {
3289
- closeProducers (partitions );
3212
+ catch (Exception e ) {
3213
+ ListenerConsumer .this .logger .error (e , () -> "Fatal commit error after revocation "
3214
+ + partitions );
3215
+ }
3216
+ if (this .consumerAwareListener != null ) {
3217
+ this .consumerAwareListener .onPartitionsRevokedAfterCommit (ListenerConsumer .this .consumer ,
3218
+ partitions );
3219
+ }
3220
+ if (ListenerConsumer .this .consumerSeekAwareListener != null ) {
3221
+ ListenerConsumer .this .consumerSeekAwareListener .onPartitionsRevoked (partitions );
3222
+ }
3223
+ if (ListenerConsumer .this .assignedPartitions != null ) {
3224
+ ListenerConsumer .this .assignedPartitions .removeAll (partitions );
3225
+ }
3226
+ ListenerConsumer .this .pausedForNack .removeAll (partitions );
3227
+ partitions .forEach (tp -> ListenerConsumer .this .lastCommits .remove (tp ));
3228
+ synchronized (ListenerConsumer .this ) {
3229
+ if (ListenerConsumer .this .offsetsInThisBatch != null ) {
3230
+ partitions .forEach (tp -> {
3231
+ ListenerConsumer .this .offsetsInThisBatch .remove (tp );
3232
+ ListenerConsumer .this .deferredOffsets .remove (tp );
3233
+ });
3290
3234
}
3291
3235
}
3292
3236
}
@@ -3349,33 +3293,25 @@ private void commitCurrentOffsets(Map<TopicPartition, OffsetAndMetadata> offsets
3349
3293
if (ListenerConsumer .this .transactionTemplate != null
3350
3294
&& ListenerConsumer .this .kafkaTxManager != null
3351
3295
&& !AssignmentCommitOption .LATEST_ONLY_NO_TX .equals (ListenerConsumer .this .autoCommitOption )) {
3352
- try {
3353
- offsetsToCommit .forEach ((partition , offsetAndMetadata ) -> {
3354
- if (ListenerConsumer .this .producerPerConsumerPartition ) {
3355
- TransactionSupport .setTransactionIdSuffix (
3356
- zombieFenceTxIdSuffix (partition .topic (), partition .partition ()));
3357
- }
3358
- ListenerConsumer .this .transactionTemplate
3359
- .execute (new TransactionCallbackWithoutResult () {
3360
-
3361
- @ Override
3362
- protected void doInTransactionWithoutResult (TransactionStatus status ) {
3363
- KafkaResourceHolder <?, ?> holder =
3364
- (KafkaResourceHolder <?, ?>) TransactionSynchronizationManager
3365
- .getResource (ListenerConsumer .this .kafkaTxManager
3366
- .getProducerFactory ());
3367
- if (holder != null ) {
3368
- doSendOffsets (holder .getProducer (),
3369
- Collections .singletonMap (partition , offsetAndMetadata ));
3370
- }
3296
+
3297
+ offsetsToCommit .forEach ((partition , offsetAndMetadata ) -> {
3298
+ ListenerConsumer .this .transactionTemplate
3299
+ .execute (new TransactionCallbackWithoutResult () {
3300
+
3301
+ @ Override
3302
+ protected void doInTransactionWithoutResult (TransactionStatus status ) {
3303
+ KafkaResourceHolder <?, ?> holder =
3304
+ (KafkaResourceHolder <?, ?>) TransactionSynchronizationManager
3305
+ .getResource (ListenerConsumer .this .kafkaTxManager
3306
+ .getProducerFactory ());
3307
+ if (holder != null ) {
3308
+ doSendOffsets (holder .getProducer (),
3309
+ Collections .singletonMap (partition , offsetAndMetadata ));
3371
3310
}
3311
+ }
3372
3312
3373
- });
3374
- });
3375
- }
3376
- finally {
3377
- TransactionSupport .clearTransactionIdSuffix ();
3378
- }
3313
+ });
3314
+ });
3379
3315
}
3380
3316
else {
3381
3317
ContainerProperties containerProps = KafkaMessageListenerContainer .this .getContainerProperties ();
0 commit comments