首页 > 解决方案 > Spring Batch:在 SpringBoot 中使用 SkipPolicy 和 RetryPolicy

问题描述

我最近开始学习 Spring Batch 并为一个项目做 POC,我坚持重试策略和跳过策略。我在获得这些问题的解决方案时有点模棱两可

问题1):我们可以在一个实例上同时使用SkipPolicy和Retry Policy吗,读者有一个例外,现在框架会寻找我们定义的策略。它会同时适用于政策还是我们首先定义的政策..?(我已经在我的 POC 中实现了这一点,但它只会跳过策略而不是重试策略)我要检查的是,如果异常是 Skippable 的实例,那么如果异常是实例,则执行我的业务逻辑可重试,然后重试一定的限制。

问题 2):如何获取失败记录的数据,我知道有侦听器(ReadListener、WriteListener、ProcessListener)但是,如果重试超过限制,我想记录哪个记录确实导致了该异常。

问题 3):有什么方法可以在将批处理写入数据库或将其写入某个地方(CSV 或平面文件)时获得准确的失败记录

我确实尝试过这些场景,但无法清楚地理解这一点。

任何帮助将不胜感激:)

这是步骤配置

@Bean
public Step step() {
    return stepBuilderFactory.get("eventStep")
            .<Employee, Employee>chunk(3)
            .reader(employeeItemReader())
            .listener(stepItemReadListener)
            .listener(noWorkFoundStepExecutionListener)
            .listener(new StepItemReadListener())
            .processor(processor())
            .writer(writer())
            .faultTolerant()
            .skipPolicy(dbConnectivitySkipper)
            .retryPolicy(stepRetry)
            .listener(stepItemWriteListner)
            .build();
}

跳过政策的实施

@Override
public boolean shouldSkip(Throwable exception, int skipCount) throws SkipLimitExceededException {

    if (exception instanceof DuplicateKeyException && skipCount <= 5) {
        return true;
    } else  if (exception instanceof  NumberFormatException && skipCount <= 5){
        return true;
    } else {
        return false;
    }

重试策略的实施

公共布尔canRetry(RetryContext上下文){

    Throwable t = context.getLastThrowable();
    if (t instanceof NullPointerException && context.getRetryCount() <= maxAttempts) {
        return true;
    } else  if (t instanceof StepListenerFailedException && context.getRetryCount() <= maxAttempts){
        return true;
    } else {
        return false;
    }
}

标签: javaspring-batch

解决方案


您的问题中有很多细节,我将尝试提供尽可能多的见解:

问题一:

重试策略不适用于项目阅读器。因此,即使您将异常声明为可重试并且读取器抛出该异常,重试策略也不会被调用。这就是为什么您只看到正在应用的跳过策略。

问题2

如果超过重试限制,那么您的作业将失败。在这种情况下,您可以使用JobExecution#getAllFailureExceptions. 最后一个失败异常应该告诉您哪个项目导致重试限制用尽。

问题 3

当 writer 中抛出可跳过的异常时,Spring Batch 无法知道是哪个项目导致块失败。在这种情况下,它将通过一次尝试一个项目来“扫描”块(它实际上会将块大小更改为 1 并为每个项目发出一个事务)。因此,只会跳过有缺陷的项目。通过使用跳过侦听器,您可以准确地获得您正在寻找的项目。

希望这可以帮助。


推荐阅读