在Spring Batch中配置重试逻辑 - Baeldung


默认情况下,Spring批处理作业因执行期间引发的任何错误而失败。但是,有时,我们可能需要提高应用程序的弹性来处理间歇性故障。在本快速教程中,我们将探索如何在Spring Batch框架中配置重试逻辑。
假设我们有一个批处理作业,它读取输入的CSV文件:

username, userid, transaction_date, transaction_amount
sammy, 1234, 31/10/2015, 10000
john, 9999, 3/12/2015, 12321

然后,它通过点击REST端点以获取用户的age和postCode属性来处理每条记录:

public class RetryItemProcessor implements ItemProcessor<Transaction, Transaction> {
     
    @Override
    public Transaction process(Transaction transaction) throws IOException {
        log.info("RetryItemProcessor, attempting to process: {}", transaction);
        HttpResponse response = fetchMoreUserDetails(transaction.getUserId());
        
//parse user's age and postCode from response and update transaction
        ...
        return transaction;
    }
    ...
}

最后,它生成一个合并的输出XML:
<transactionRecord>
    <transactionRecord>
        <amount>10000.0</amount>
        <transactionDate>2015-10-31T00:00:00+05:30</transactionDate>
        <userId>1234</userId>
        <username>sammy</username>
        <age>10</age>
        <postCode>430222</postCode>
    </transactionRecord>
    ...
</transactionRecord>

现在,如果由于某些网络缓慢而导致与REST端点的连接超时怎么办?如果是这样,我们的批处理作业将失败。
在这种情况下,我们希望重试失败的项目两次。因此,让我们将批处理作业配置为在失败的情况下最多执行三个重试:

@Bean
public Step retryStep(
  ItemProcessor<Transaction, Transaction> processor,
  ItemWriter<Transaction> writer) throws ParseException {
    return stepBuilderFactory
      .get("retryStep")
      .<Transaction, Transaction>chunk(10)
      .reader(itemReader(inputCsv))
      .processor(processor)
      .writer(writer)
      .faultTolerant()
      .retryLimit(3)
      .retry(ConnectTimeoutException.class)
      .retry(DeadlockLoserDataAccessException.class)
      .build();
}

在这里,我们调用faultTolerant() 以启用重试功能。此外,我们使用retry和retryLimit分别定义了符合重试条件的异常和项的最大重试计数。

看一下上述配置的XML等效配置:

<batch:job id="retryBatchJob">
    <batch:step id=
"retryStep">
        <batch:tasklet>
            <batch:chunk reader=
"itemReader" writer="itemWriter"
              processor=
"retryItemProcessor" commit-interval="10"
              retry-limit=
"3">
                <batch:retryable-exception-classes>
                    <batch:include class=
"org.apache.http.conn.ConnectTimeoutException"/>
                    <batch:include class=
"org.springframework.dao.DeadlockLoserDataAccessException"/>
                </batch:retryable-exception-classes>
            </batch:chunk>
        </batch:tasklet>
    </batch:step>
</batch:job>