如何使用spring RetryTemplate在每次尝试中执行恢复逻辑

时间:2019-06-18 21:44:50

标签: spring spring-retry

我有一个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

1 个答案:

答案 0 :(得分:0)

带有重试模板的“恢复”的整个概念是在重试用尽之后采取一些措施。它并非旨在满足您的需求。