Пружинная повторная попытка не работает с retrytemplate - PullRequest
0 голосов
/ 14 октября 2018

В этом примере я попытался выполнить повторную попытку пружины. Функция повтора не работает в Spring Batch и работает.Я пытаюсь добиться того же с помощью retrytemplate, но не вижу, что повторная попытка не работает, когда выдается исключение.

        @Configuration
            @EnableBatchProcessing
        //@EnableRetry
        public class RetryBatchJob {

          @Autowired
          private JobBuilderFactory jobs;

          @Autowired
          private StepBuilderFactory steps;

          @Bean
          public ItemReader<Integer> itemReader() {
            return new ListItemReader<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
          }

          @Bean
          public ItemWriter<Integer> itemWriter() {
            return items -> {
              for (Integer item : items) {
                System.out.println("item = " + item);
                if (item.equals(7)) {
                  throw new Exception("Sevens are sometime nasty, let's retry them");
                }
              }
            };
          }

          @Bean
          public Step step() {
            return steps.get("step")
              .<Integer, Integer>chunk(2)
              .reader(itemReader())
              .writer(itemWriter())
              /*.faultTolerant()
              .retryLimit(5)
              .retry(Exception.class)*/
              .build();
          }

          @Bean  
          public Job job() {
            Job job = null;
            try {
              job = retryTemplate().execute(new RetryCallback<Job, Throwable>() {
                @Override
                public Job doWithRetry(RetryContext context) throws Throwable {
                  return jobs.get("job")
                    .start(step())
                    .build();
                }
              });
            } catch (Throwable throwable) {
              throwable.printStackTrace();
            }
            return job;
          }

          public static void main(String[] args) throws Exception {
            ApplicationContext context = new AnnotationConfigApplicationContext(RetryBatchJob.class);
            JobLauncher jobLauncher = context.getBean(JobLauncher.class);
            Job job = context.getBean(Job.class);
            jobLauncher.run(job, new JobParameters());
          }

          @Bean
          public RetryTemplate retryTemplate() {
            RetryTemplate retryTemplate = new RetryTemplate();

            SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(5, singletonMap(Exception.class, true));
            retryPolicy.setMaxAttempts(5);
            retryTemplate.setRetryPolicy(retryPolicy);

            return retryTemplate;
          }

        }

Я что-то упускаю, когда использую RetryTemplate?Я также попробовал декларативную настройку на шаге и методах задания, но не повезло.

@Retryable(value = {Exception.class},
 maxAttemptsExpression = "5"
)

Примечание: с использованием пружинного повтора 1.2.2 RELEASE.

Ответы [ 2 ]

0 голосов
/ 16 августа 2019

Выданные исключения во время выполнения задания не останавливают выполнение, задание продолжается до тех пор, пока не вернет результат выполнения, либо СБОЙ, либо ВЫПОЛНЕНО ... Что делает его положительным результатом для RetryTemplate.execute ().Вы можете воспользоваться возвращенным состоянием выполнения, чтобы вызвать исключение runtimeException в случае сбоя.

RetryTemplate template = new RetryTemplate();

    ExponentialBackOffPolicy exponentialBackOffPolicy = new ExponentialBackOffPolicy();
    exponentialBackOffPolicy.setInitialInterval(5000);
    exponentialBackOffPolicy.setMultiplier(ExponentialBackOffPolicy.DEFAULT_MULTIPLIER);
    exponentialBackOffPolicy.setMaxInterval(ExponentialBackOffPolicy.DEFAULT_MAX_INTERVAL);

    Map<Class<? extends Throwable>, Boolean> exceptions = new HashMap<>();
    exceptions.put(Exception.class, true);
    SimpleRetryPolicy policy = new SimpleRetryPolicy(3, exceptions);

    template.setRetryPolicy(policy);
    template.setBackOffPolicy(exponentialBackOffPolicy);

    template.execute(new RetryCallback<JobExecution, Exception>() {

        @Override
        public JobExecution doWithRetry(RetryContext context) throws Exception {        
            return runJob(job, paramMap);
        }
    });

Функция: runJob ()

public JobExecution runJob(Job job, Map<String, JobParameter> paramMap) throws Exception {
    JobExecution exe = jobLauncher.run(job, new JobParameters(paramMap));       
    if(exe.getStatus().equals(BatchStatus.FAILED))
        throw new RuntimeException(exe.toString());
    return exe;     
}
0 голосов
/ 15 октября 2018

Метод @Bean public Job job() { ... } предназначен для определения Spring Bean типа Job.Согласно вашему коду, вы вызываете retryTemplate().execute внутри этого метода и ожидаете, что задание будет повторено.Это не правильно.

Сначала вы можете определить свою работу следующим образом:

@Bean  
public Job job() {
    return jobs.get("job")
                .start(step())
                .build();
}

, а затем вызвать шаблон повтора для bean-объекта задания, полученного из контекста приложения, в * 1009.* method, что-то вроде:

public static void main(String[] args) throws Exception {
        ApplicationContext context = new AnnotationConfigApplicationContext(RetryBatchJob.class);
        JobLauncher jobLauncher = context.getBean(JobLauncher.class);
        Job job = context.getBean(Job.class);
        RetryTemplate retryTemplate = context.getBean(RetryTemplate.class);
        retryTemplate.execute(new RetryCallback<JobExecution, Exception>() {
            @Override
            public JobExecution doWithRetry(RetryContext context) throws Exception {
                return jobLauncher.run(job, new JobParameters());
            };
        });
}

Если я правильно понимаю, вы пытаетесь автоматически повторить неудачную работу с помощью шаблона повторных попыток, что-то похожее на то, что предлагается в этом PR: https://github.com/spring-projects/spring-batch/pull/440.

В любом случае, я надеюсь, что пример поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...