admin管理员组文章数量:1419250
I've started using the @Retryable annotation in my Spring Boot application (Spring Boot 2.7.18, JDK 21) and it works perfectly fine!
Below are some relevant extracts from the code:
@EnableRetry
@EnableTransactionManagement
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
@Service
public class MyService {
@Retryable(
retryFor = {LockAcquisitionException.class, SQLServerException.class},
maxAttempts = 5,
backoff = @Backoff(delay = 500),
listeners = "myRetryListener"
)
@Transactional
@Override
public void doSomething() throws MyException {
// Does something
}
}
public class MyRetryListener implements RetryListener {
@Override
public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
log.info("Retry open.");
return true;
}
@Override
public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
int attempt = context.getRetryCount();
if (throwable == null) {
log.info("Operation succeeded after {} attempts.", attempt);
} else {
log.info("Operation failed after {} attempts.", attempt);
}
}
@Override
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
log.warn("Inner retry {} of {} failed due to: {}", context.getRetryCount(), context.getAttribute("context.max-attempts"), throwable.getMessage());
}
}
HOWEVER, when I run an integration test for the application, although the retry mechanism works, it only retries once. I suspect I am missing some initialization in the test, but I cannot figure out what it is.
Has anyone experienced anything similar?
@SpringBootTest
@ActiveProfiles("test")
@EnableAutoConfiguration
@AutoConfigureMockMvc
class MyApplicationIntegrationTest {
}
The application writes some records to a MS SQL Server database, which I have simulated in test with an H2 in memory database. In the integration test I throw a SQLException via a 'BEFORE INSERT' trigger in the H2 table.
The output of the application is, as expected:
2025-01-29 12:05:14 INFO .MyRetryListener : Retry open.
2025-01-29 12:05:15 WARN SqlExceptionHelper : SQL Error: 50000, SQLState: S0001
2025-01-29 12:05:15 ERROR SqlExceptionHelper : Simulated SQLException for testing
2025-01-29 12:05:15 WARN .MyRetryListener : Inner retry 1 of 5 failed due to: Could not persist entities
2025-01-29 12:05:15 WARN SqlExceptionHelper : SQL Error: 50000, SQLState: S0001
2025-01-29 12:05:15 ERROR SqlExceptionHelper : Simulated SQLException for testing
2025-01-29 12:05:15 WARN .MyRetryListener : Inner retry 2 of 5 failed due to: Could not persist entities
2025-01-29 12:05:16 WARN SqlExceptionHelper : SQL Error: 50000, SQLState: S0001
2025-01-29 12:05:16 ERROR SqlExceptionHelper : Simulated SQLException for testing
2025-01-29 12:05:16 WARN .MyRetryListener : Inner retry 3 of 5 failed due to: Could not persist entities
2025-01-29 12:05:16 WARN SqlExceptionHelper : SQL Error: 50000, SQLState: S0001
2025-01-29 12:05:16 ERROR SqlExceptionHelper : Simulated SQLException for testing
2025-01-29 12:05:16 WARN .MyRetryListener : Inner retry 4 of 5 failed due to: Could not persist entities
2025-01-29 12:05:17 WARN SqlExceptionHelper : SQL Error: 50000, SQLState: S0001
2025-01-29 12:05:17 ERROR SqlExceptionHelper : Simulated SQLException for testing
2025-01-29 12:05:17 WARN .MyRetryListener : Inner retry 5 of 5 failed due to: Could not persist entities
2025-01-29 12:05:17 INFO .MyRetryListener : Operation failed after 5 attempts.
while the output of the test is, sadly:
2025:01:29 12:12:37 INFO .MyRetryListener : Retry open.
2025:01:29 12:12:37 WARN TriggerImpl : Executing database trigger H2TriggerImpl: Simulated SQLException for testing
2025:01:29 12:12:37 WARN SqlExceptionHelper : SQL Error: 0, SQLState: null
2025:01:29 12:12:37 ERROR SqlExceptionHelper : Simulated SQLException for testing
2025:01:29 12:12:37 INFO .AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
2025:01:29 12:12:38 WARN .MyRetryListener : Inner retry 1 of 5 failed due to: Could not persist entities
2025:01:29 12:12:38 INFO .MyRetryListener : Operation failed after 1 attempts.
I've started using the @Retryable annotation in my Spring Boot application (Spring Boot 2.7.18, JDK 21) and it works perfectly fine!
Below are some relevant extracts from the code:
@EnableRetry
@EnableTransactionManagement
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
@Service
public class MyService {
@Retryable(
retryFor = {LockAcquisitionException.class, SQLServerException.class},
maxAttempts = 5,
backoff = @Backoff(delay = 500),
listeners = "myRetryListener"
)
@Transactional
@Override
public void doSomething() throws MyException {
// Does something
}
}
public class MyRetryListener implements RetryListener {
@Override
public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
log.info("Retry open.");
return true;
}
@Override
public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
int attempt = context.getRetryCount();
if (throwable == null) {
log.info("Operation succeeded after {} attempts.", attempt);
} else {
log.info("Operation failed after {} attempts.", attempt);
}
}
@Override
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
log.warn("Inner retry {} of {} failed due to: {}", context.getRetryCount(), context.getAttribute("context.max-attempts"), throwable.getMessage());
}
}
HOWEVER, when I run an integration test for the application, although the retry mechanism works, it only retries once. I suspect I am missing some initialization in the test, but I cannot figure out what it is.
Has anyone experienced anything similar?
@SpringBootTest
@ActiveProfiles("test")
@EnableAutoConfiguration
@AutoConfigureMockMvc
class MyApplicationIntegrationTest {
}
The application writes some records to a MS SQL Server database, which I have simulated in test with an H2 in memory database. In the integration test I throw a SQLException via a 'BEFORE INSERT' trigger in the H2 table.
The output of the application is, as expected:
2025-01-29 12:05:14 INFO .MyRetryListener : Retry open.
2025-01-29 12:05:15 WARN SqlExceptionHelper : SQL Error: 50000, SQLState: S0001
2025-01-29 12:05:15 ERROR SqlExceptionHelper : Simulated SQLException for testing
2025-01-29 12:05:15 WARN .MyRetryListener : Inner retry 1 of 5 failed due to: Could not persist entities
2025-01-29 12:05:15 WARN SqlExceptionHelper : SQL Error: 50000, SQLState: S0001
2025-01-29 12:05:15 ERROR SqlExceptionHelper : Simulated SQLException for testing
2025-01-29 12:05:15 WARN .MyRetryListener : Inner retry 2 of 5 failed due to: Could not persist entities
2025-01-29 12:05:16 WARN SqlExceptionHelper : SQL Error: 50000, SQLState: S0001
2025-01-29 12:05:16 ERROR SqlExceptionHelper : Simulated SQLException for testing
2025-01-29 12:05:16 WARN .MyRetryListener : Inner retry 3 of 5 failed due to: Could not persist entities
2025-01-29 12:05:16 WARN SqlExceptionHelper : SQL Error: 50000, SQLState: S0001
2025-01-29 12:05:16 ERROR SqlExceptionHelper : Simulated SQLException for testing
2025-01-29 12:05:16 WARN .MyRetryListener : Inner retry 4 of 5 failed due to: Could not persist entities
2025-01-29 12:05:17 WARN SqlExceptionHelper : SQL Error: 50000, SQLState: S0001
2025-01-29 12:05:17 ERROR SqlExceptionHelper : Simulated SQLException for testing
2025-01-29 12:05:17 WARN .MyRetryListener : Inner retry 5 of 5 failed due to: Could not persist entities
2025-01-29 12:05:17 INFO .MyRetryListener : Operation failed after 5 attempts.
while the output of the test is, sadly:
2025:01:29 12:12:37 INFO .MyRetryListener : Retry open.
2025:01:29 12:12:37 WARN TriggerImpl : Executing database trigger H2TriggerImpl: Simulated SQLException for testing
2025:01:29 12:12:37 WARN SqlExceptionHelper : SQL Error: 0, SQLState: null
2025:01:29 12:12:37 ERROR SqlExceptionHelper : Simulated SQLException for testing
2025:01:29 12:12:37 INFO .AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
2025:01:29 12:12:38 WARN .MyRetryListener : Inner retry 1 of 5 failed due to: Could not persist entities
2025:01:29 12:12:38 INFO .MyRetryListener : Operation failed after 1 attempts.
Share
Improve this question
asked Jan 29 at 12:23
GepGep
9283 gold badges16 silver badges33 bronze badges
4
|
2 Answers
Reset to default 1According to your configuration only these exceptions are retryable:
retryFor = {LockAcquisitionException.class, SQLServerException.class},
So, make sure that your test environment throws one of those. All other exceptions are not retryable.
I do not have enough stackoverflow points so I am responding via an answer.
Given that you have LockAcquisition
, I assume you are using a version column.
If you are using versioning, there are some additional annotations you might require depending on what type of locking approach you are taking.
For instance, for optimistic locking there's the annotation below where you can specify the exact lock type mode you want.
@Lock(LockModeType.OPTIMISTIC_FORCE_INCREMENT)
And also exceptions related to optimistic locking such as OptimisticLockException.class
, CannotAcquireLockException.class
, UnexpectedRollbackException.class
, etc based on your requirements..
If this isn't the case, let me know and I can try to help as I have PROD experience with having to implement retryable.
本文标签: javaRetryable only retrying once in integration testStack Overflow
版权声明:本文标题:java - @Retryable only retrying once in integration test - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745298252a2652210.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
retryFor = {LockAcquisitionException.class, SQLServerException.class}
, but probably your test environment doesn't not throw those exceptions. Some other instead, which is not retryable. – Artem Bilan Commented Jan 31 at 15:42