Можем ли мы обработать вложенные исключения с помощью весеннего повтора? - PullRequest
0 голосов
/ 07 января 2020

Я изучаю Spring Retry и у меня следующий вопрос о его возможностях:

У меня есть функция, которая подключается к стороннему API приложения. Ожидается, что это может вызвать различные исключения, такие как исключения Timeout или IO. Я пытался понять, сможет ли шаблон повторения Spring обработать такие вложенные исключения в «каждом» случае. Например, когда мы устанавливаем maxAttempts равным 3 для отдельных исключений, он должен повторять попытки 3 раза в каждом случае, даже если он находится в пределах повторной попытки. например, при попытке 1 - возникла исключительная ситуация 1, а при следующей попытке (попытка 2) она была успешной, но теперь возникает исключение 2, на основе retryPolicy она должна инициировать попытку 1 для исключения 2.

Возможно ли это?

Исходя из небольшого PO C, я вижу, что он пробовал только 3 раза, даже когда оба типа были выброшены:

Класс контроллера с retryTemplate:

         retryTemplate.execute(new RetryCallback<Customer, Exception>(){
             @Override
                public Customer doWithRetry(RetryContext arg0) throws Exception{
                System.out.println("count #"+arg0.getRetryCount());
                if(arg0.getRetryCount()>0) {
                    System.out.println("throwable getClass Canonical Name "+arg0.getLastThrowable().getClass().getCanonicalName());
                }

                return  customerService.getCustomerDetails(choice);
             }});

Класс имитации исключения:

Random r = new Random();

            int i = r.nextInt();
            i+=1;

            System.out.println("value of i "+i);
            if(i%2==0) {
                throw new Exception1();
            }
            else {
                throw new Exception2();
            }

Вот журналы:

count #0
in getCustomerDetails
value of i -1050226395
count #1
throwable getClass Canonical Name Exception1
in getCustomerDetails
value of i 824190506
count #2
throwable getClass Canonical Name Exception2
in getCustomerDetails
value of i 1210506150
Exception1

Ожидаемый результат: попытка 3 раза для каждого случая исключения

Фактический результат: Он пытается только на общую сумму 3.

Ниже приведен мой RetryPolicy: ExceptionClassifierRetryPolicy имеет policyMap для обоих типов исключений

public RetryTemplate retryTemplate() {

    RetryTemplate retryTemplate = new RetryTemplate();
    final SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy();
    simpleRetryPolicy.setMaxAttempts(3);
    FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
    backOffPolicy.setBackOffPeriod(1500);
    final Map<Class<? extends Throwable>, RetryPolicy> policyMap = new HashMap<>();
    policyMap.put(Exception1.class, simpleRetryPolicy);
    policyMap.put(Exception2.class, simpleRetryPolicy);
    final ExceptionClassifierRetryPolicy retryPolicy = new ExceptionClassifierRetryPolicy();
    retryPolicy.setPolicyMap(policyMap);
    retryTemplate.setBackOffPolicy(backOffPolicy);
    retryTemplate.setRetryPolicy(retryPolicy);
    return retryTemplate;
}

Вопросы:

  1. Может Для этого сценария будет использоваться повторный запуск?
  2. Если да, что необходимо изменить в приведенной выше реализации?

Пожалуйста, руководство.

1 Ответ

2 голосов
/ 07 января 2020

Вы можете использовать ExceptionClassifierRetryPolicy, но обязательно назначьте разные экземпляры SimpleRetryPolicy для каждого типа исключения:

ExceptionClassifierRetryPolicy retryPolicy = new ExceptionClassifierRetryPolicy();
Map<Class<? extends Throwable>, RetryPolicy> policyMap = new HashMap<>();

policyMap.put(Exception1.class, new SimpleRetryPolicy(3));
policyMap.put(Exception2.class, new SimpleRetryPolicy(3));

retryPolicy.setPolicyMap(policyMap);
retryTemplate.setRetryPolicy(retryPolicy);
...