@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());
}
}
但是,当我对应用程序进行集成测试时,尽管重试机制起作用,但它只能重试。我怀疑我在测试中缺少一些初始化,但我无法弄清楚它是什么。
有人经历了类似的事情吗?@SpringBootTest
@ActiveProfiles("test")
@EnableAutoConfiguration
@AutoConfigureMockMvc
class MyApplicationIntegrationTest {
}
应用程序将一些记录写入MS SQL Server数据库,我在内存数据库中使用H2进行了测试。在集成测试中,我通过a在H2表中插入“插入”触发器的sqlexception。
应用程序的输出是预期的:
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.
可悲的是,测试的输出是:
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.
我没有足够的堆叠点点,所以我通过答案做出回答。 我认为您正在使用“ LockAciquition”,我认为您正在使用版本列。
如果您使用的是版本控制,则可能需要一些其他注释,具体取决于您采用哪种锁定方法。实例,为了乐观的锁定,下面有注释,您可以在其中指定所需的确切锁定类型模式。
@@lock(lockmodetype.optimistic_force_increment)还与乐观锁定有关的例外,例如OpportisticLockexception.Class,Chotacquirelockexception.Class,意外的Rollbackexception.class.class等,根据您的要求..如果不是这种情况,请告诉我,我可以尝试提供帮助,因为我拥有必须实施重击的经验。