我有一个Spring RetryTemplate,它包装了一组对数据库包装服务的http调用,这些组合在一起具有事务性,这意味着如果最后一个失败,我需要回滚所有先前执行的操作,并开始处理全部结束。
问题在于,仅在上一次失败尝试后才执行恢复,这使问题比我尝试解决的问题更大:
我的数据库状态在每次尝试之间都是不一致的。
如何在每次失败的尝试中实现恢复执行?
我尝试自己编写样板代码。除了外观难看之外,我更喜欢一种经过良好测试和设计的方法。
//I'm only experimenting now, when I'm done the template and policy will be injected.
RetryTemplate relshpProcessRetry = new RetryTemplate();
SimpleRetryPolicy retryPolicy=new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(3);
relshpProcessRetry.setRetryPolicy(retryPolicy);
try {
relshpProcessRetry
.execute((RetryCallback<Void, StorageAccessorException>) context -> {
final var decisions = decideRelationships(relationshipRequest).getDecisions();
context
.setAttribute(String.valueOf(relationshipRequest.getParentListingId()), decisions);
decisions
.forEach(relationshipDecision -> relationshipDecision.apply(storageAccessor));
return null;
}, context -> {
//noinspection unchecked
List<RelationshipDecision> decisions = (List<RelationshipDecision>) context
.getAttribute(String.valueOf(relationshipRequest.getParentListingId()));
//noinspection ConstantConditions
Validate.notEmpty(decisions, "Decisions to rollback must not be null");
ReverseListIterator<RelationshipDecision> decisionReverseIterator = new ReverseListIterator<>(
decisions);
while (decisionReverseIterator.hasNext()) {
final var decision = decisionReverseIterator.next();
if (decision.isApplied()) {
decision.rollback(storageAccessor);
}
}
return null;
});
} catch (ExhaustedRetryException e) {
//if we are here, all attempts ended in optimistic lock exceptions
log.debug(
"Failed to process relationship(s) for request {} , after all retry attempts have been exhausted",
relationshipRequest, e);
throw new IllegalStateException(
"Relationship processing failed - " + relationshipRequest.toString(), e);
}
在单元测试中,我看到在第一次恢复之前已打印以下内容:
14:24:38.882 [main] DEBUG org.springframework.retry.support.RetryTemplate - Retry: count=0
14:24:40.726 [main] DEBUG org.springframework.retry.support.RetryTemplate - Checking for rethrow: count=1
14:24:40.726 [main] DEBUG org.springframework.retry.support.RetryTemplate - Retry: count=1
14:24:41.843 [main] DEBUG org.springframework.retry.support.RetryTemplate - Checking for rethrow: count=2
14:24:41.843 [main] DEBUG org.springframework.retry.support.RetryTemplate - Retry: count=2
14:24:42.781 [main] DEBUG org.springframework.retry.support.RetryTemplate - Checking for rethrow: count=3
14:24:42.781 [main] DEBUG org.springframework.retry.support.RetryTemplate - Retry failed last attempt: count=3
答案 0 :(得分:0)
带有重试模板的“恢复”的整个概念是在重试用尽之后采取一些措施。它并非旨在满足您的需求。