Skip to content

Commit 468784e

Browse files
authored
GH-10345: Replace Spring Retry in the JDBC module
Related to: #10345 Migrate the only class in the ` jdbc ` module - `PostgresSubscribableChannel`, - to the Core Retry
1 parent a7d1f96 commit 468784e

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/channel/PostgresSubscribableChannel.java

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,24 @@
1616

1717
package org.springframework.integration.jdbc.channel;
1818

19+
import java.time.Duration;
1920
import java.util.Optional;
2021
import java.util.concurrent.Executor;
2122

2223
import org.jspecify.annotations.Nullable;
2324

2425
import org.springframework.core.log.LogAccessor;
26+
import org.springframework.core.retry.RetryException;
27+
import org.springframework.core.retry.RetryPolicy;
28+
import org.springframework.core.retry.RetryTemplate;
29+
import org.springframework.core.retry.Retryable;
2530
import org.springframework.core.task.SimpleAsyncTaskExecutor;
2631
import org.springframework.integration.channel.AbstractSubscribableChannel;
2732
import org.springframework.integration.dispatcher.MessageDispatcher;
2833
import org.springframework.integration.dispatcher.UnicastingDispatcher;
2934
import org.springframework.integration.jdbc.store.JdbcChannelMessageStore;
3035
import org.springframework.messaging.Message;
3136
import org.springframework.messaging.MessageHandler;
32-
import org.springframework.retry.support.RetryTemplate;
3337
import org.springframework.transaction.PlatformTransactionManager;
3438
import org.springframework.transaction.support.TransactionTemplate;
3539
import org.springframework.util.Assert;
@@ -69,7 +73,8 @@ public class PostgresSubscribableChannel extends AbstractSubscribableChannel
6973

7074
private @Nullable TransactionTemplate transactionTemplate;
7175

72-
private RetryTemplate retryTemplate = RetryTemplate.builder().maxAttempts(1).build();
76+
private RetryTemplate retryTemplate =
77+
new RetryTemplate(RetryPolicy.builder().maxAttempts(1).delay(Duration.ZERO).build());
7378

7479
private ErrorHandler errorHandler = ReflectionUtils::rethrowRuntimeException;
7580

@@ -117,7 +122,7 @@ public void setTransactionManager(PlatformTransactionManager transactionManager)
117122
}
118123

119124
/**
120-
* Set the retry template to use for retries in case of exception in downstream processing
125+
* Set the retry template to use it for retries in case of exception in downstream processing
121126
* @param retryTemplate The retry template to use
122127
* @since 6.0.5
123128
* @see RetryTemplate
@@ -207,7 +212,7 @@ private Optional<?> doPollAndDispatchMessage() {
207212
if (this.hasHandlers) {
208213
TransactionTemplate transactionTemplateToUse = this.transactionTemplate;
209214
if (transactionTemplateToUse != null) {
210-
return this.retryTemplate.execute(context ->
215+
return executeWithRetry(() ->
211216
transactionTemplateToUse.execute(status ->
212217
pollMessage()
213218
.filter(message -> {
@@ -221,12 +226,26 @@ private Optional<?> doPollAndDispatchMessage() {
221226
}
222227
else {
223228
return pollMessage()
224-
.map(message -> this.retryTemplate.execute(context -> dispatch(message)));
229+
.map(message -> executeWithRetry(() -> dispatch(message)));
225230
}
226231
}
227232
return Optional.empty();
228233
}
229234

235+
@SuppressWarnings("NullAway") // Never null, according to the logic in the 'doPollAndDispatchMessage()'.
236+
private <T> T executeWithRetry(Retryable<T> retryable) {
237+
try {
238+
return this.retryTemplate.execute(retryable);
239+
}
240+
catch (RetryException ex) {
241+
Throwable cause = ex.getCause();
242+
if (cause instanceof RuntimeException runtimeException) {
243+
throw runtimeException;
244+
}
245+
throw new IllegalStateException(cause);
246+
}
247+
}
248+
230249
private Optional<Message<?>> pollMessage() {
231250
return Optional.ofNullable(this.jdbcChannelMessageStore.pollMessageFromGroup(this.groupId));
232251
}

spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/postgres/PostgresChannelMessageTableSubscriberTests.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
import org.springframework.context.annotation.Bean;
4444
import org.springframework.context.annotation.Configuration;
4545
import org.springframework.core.io.ByteArrayResource;
46+
import org.springframework.core.retry.RetryPolicy;
47+
import org.springframework.core.retry.RetryTemplate;
4648
import org.springframework.integration.config.EnableIntegration;
4749
import org.springframework.integration.jdbc.channel.PgConnectionSupplier;
4850
import org.springframework.integration.jdbc.channel.PostgresChannelMessageTableSubscriber;
@@ -57,7 +59,6 @@
5759
import org.springframework.messaging.MessageHandler;
5860
import org.springframework.messaging.MessagingException;
5961
import org.springframework.messaging.support.GenericMessage;
60-
import org.springframework.retry.support.RetryTemplate;
6162
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
6263
import org.springframework.test.annotation.DirtiesContext;
6364
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
@@ -246,7 +247,8 @@ void testRetryOnErrorDuringDispatch(boolean transactionsEnabled) throws Interrup
246247
AtomicInteger actualTries = new AtomicInteger();
247248

248249
int maxAttempts = 2;
249-
postgresSubscribableChannel.setRetryTemplate(RetryTemplate.builder().maxAttempts(maxAttempts).build());
250+
postgresSubscribableChannel.setRetryTemplate(
251+
new RetryTemplate(RetryPolicy.builder().maxAttempts(maxAttempts).build()));
250252

251253
if (transactionsEnabled) {
252254
postgresSubscribableChannel.setTransactionManager(transactionManager);

0 commit comments

Comments
 (0)