当前位置: 首页 > 知识库问答 >
问题:

Spring批处理默认重试策略

王棋
2023-03-14

我有以下一个批处理的Spring配置。我在生产批处理中遇到过一个问题,当一个特定的用例抛出一个不可跳过的异常时。当我在集成测试中复制用例时,批处理行为仍然很奇怪。当我的batch.commit-interval属性大于1时,将触发重试机制,回滚未提交的块,并再次处理所有以前的记录。当batch-commit-interval设置为1时,一旦抛出不可跳过的异常,批处理就会失败。

我尝试了batch-commit-interval和retry-limit的各种值。导致该问题的特殊异常是NullPointerException。我的目标是最好使用NeverRetryPolicy来处理该异常,如果不是,则使用经典的异常处理。我不想重试失败的项目处理,所以我甚至使用了NeverRetryPolicy。但似乎整个事情最终是由批处理提交间隔驱动的(使用重试限制、可重试异常类和NeverRetryPolicy似乎没有效果)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
                     http://www.springframework.org/schema/beans/spring-beans.xsd
                     http://www.springframework.org/schema/context
                     http://www.springframework.org/schema/context/spring-context.xsd
                     http://www.springframework.org/schema/batch
                     http://www.springframework.org/schema/batch/spring-batch.xsd">


<!--================ JOB & STEPS ================ -->   
<batch:job id="BEL-batch-Retry-Tests">

    <batch:step id="mainRetryTests" >
        <batch:tasklet>
            <batch:chunk  reader="jpaReaderRetryTests" processor="bdToFlatFileProcessorRetryTests" writer="flatWriterRetryTests" commit-interval="${batch.commit-interval}" skip-limit="${batch.skip-limit}">

                <batch:streams>
                    <batch:stream ref="flatWriterRetryTests" />
                </batch:streams>
                <batch:skippable-exception-classes>
                    <batch:include
                        class="org.springframework.batch.item.file.FlatFileParseException" />
                    <batch:include class="ma.awb.ebk.bel.batch.EntiteBatchInvalideException" />
                </batch:skippable-exception-classes>
            </batch:chunk>
            <batch:listeners>

                <batch:listener ref="stepListener"/>
                <batch:listener ref="skipListener"/>
            </batch:listeners>
        </batch:tasklet>

        <batch:listeners>
            <batch:listener ref="stepListener"/>
            <batch:listener ref="skipListener"/>
        </batch:listeners>
    </batch:step>

    <batch:listeners>
        <batch:listener ref="jobListener"/>
    </batch:listeners>
</batch:job>
<!--================ READERS & WRITERS ================-->

<bean id="jpaReaderRetryTests" class="org.springframework.batch.item.database.JpaPagingItemReader">
    <property name="entityManagerFactory" ref="entityManagerFactoryBel"/>
    <property name="queryString" value="select c from CaracteristiquesCarte c"/>
    <property name="pageSize" value="100"/>
</bean>

<bean id="flatWriterRetryTests" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step">
    <property name="resource" value="file:${retry-tests.outputfile.basename}-#{jobParameters['runDate']}${retry-tests.outputfile.ext}" />
    <property name="lineAggregator">
             <bean
                 class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
                 <property name="delimiter" value="${batch.file.writer.delimiter}" />
                 <property name="fieldExtractor">
                     <bean
                         class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
                         <property name="names" value="codeProduit,nomCarte,codeAAfficher,rechargeable" />
                     </bean>
                 </property>
             </bean>
     </property>

</bean>



<bean id="bdToFlatFileProcessorRetryTests" class="ma.awb.ebk.bel.batch.retry.BDToFlatFileRetryProcessor" />
package ma.awb.ebk.bel.batch.retry;

import ma.awb.ebk.bel.domain.CaracteristiquesCarte;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemProcessor;



public class BDToFlatFileRetryProcessor implements   ItemProcessor<CaracteristiquesCarte, CaracteristiquesCarte> {

private static int counter = 0;
private static final Logger LOGGER = LoggerFactory.getLogger (BDToFlatFileRetryProcessor.class);


@Override
public CaracteristiquesCarte process(CaracteristiquesCarte  caracteristiques)
        throws Exception {

    String witness = null;
    counter++;

    System.out.println("DEBUGGING iteration N° " +  counter+" "+caracteristiques.getCodeProduit());

    // Tester le cas d'un renvoie de null
    if (counter == 4) {
        System.out.println("PETTAGE " + counter);
        String test = witness.substring(2);

    }

    return caracteristiques;
}

}

共有1个答案

敖涵容
2023-03-14

我看到的问题之一是你得到了空指针,这应该永远不会发生。如果你修好了会怎么样?Rest看起来像批处理所需的行为。

 类似资料:
  • 我有以下步骤在批处理工作。 当某个异常抛出时,我在parseStepSkipListener中捕捉他并登录数据库。 我期待以下行为: 作业已启动 执行前面的步骤 开始执行解析步骤 阅读项目 进程项 写 哦,异常。 捕获异常,登录数据库,转到下一个块(读取、处理、写入)。 作业已启动 执行前面的步骤 开始执行解析步骤 阅读项目 进程项 写 哦,异常。 进程项 写入项 哦,异常。 捕获异常,登录数据库

  • 在RetryTemplate里面,执行excuter方法是重试还是失败是由RetryPolicy决定的,这也是一个RetryContext工厂.这个RetryTemplate有责任使用当前的策略创建一个RetryContext并且把它注入到RetryCallback在每一次尝试中。回调失败后RetryTemplate必须由RetryPolicy决定使其更新状态(存储在RetryContext中),

  • 有没有纯注解为Spring留档?我看到的90%的文档都是为xml实现编写的。 我正在尝试覆盖默认的JobLauncher以能够传递JobParameters,但我添加到下面代码中的任何JobLauncher函数都被忽略,而是运行默认的SimpleJobLauncher。 我想用4个不同的作业参数启动同一作业的4个并发实例。这些参数应该告诉读取器从哪个目录读取。 我可以使用@Value注释为目录传递

  • 假设我有一个像这样配置的简单任务: 当抛出MyRetryableException时,我重试了15次,但最后我得到了

  • 为了辅助批处理系统的设计和实现、应该通过结构示意图和代码实例的形式为设计师和程序员提供基础的批处理程序构建模块和以及处理模式. 在设计批处理Job时,应该将业务逻辑分解成一系列的步骤,使每个步骤都可以利用以下的标准构建模块来实现: 转换程序(Conversion Applications): 由外部系统提供或需要写入到外部系统的各种类型的文件,我们都需要为其创建一个转换程序, 用来将所提供的事务记

  • 在瞬时失效之后做一个尝试它常常有助于在再试一次之前等待一会。因为通常失败是有一些问题引起的它只能通过等待来解决这些问题,如果RetryCallback失败,RetryTemplate可以暂停执行取决于BackoffPolicy在适当的位置 public interface BackoffPolicy { BackOffContext start(RetryContext context);