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

项目处理器中的Spring批处理运行时异常

舒宏富
2023-03-14

我正在学习spring batch,并试图理解在异常期间项目处理器是如何工作的。

Jill,Doe
Joe,Doe
Justin,Doe
Jane,Doe
John,Doem
Jill,Doe
Joe,Doe
Justin,Doe
Jane,Doe
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Bean
    public FlatFileItemReader<Person> reader() {
        return new FlatFileItemReaderBuilder<Person>().name("personItemReader").resource(new ClassPathResource("sample-data.csv")).delimited()
                .names(new String[] { "firstName", "lastName" }).fieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {
                    {
                        setTargetType(Person.class);
                    }
                }).build();
    }

    @Bean
    public PersonItemProcessor processor() {
        return new PersonItemProcessor();
    }

    @Bean
    public JdbcBatchItemWriter<Person> writer(DataSource dataSource) {
        return new JdbcBatchItemWriterBuilder<Person>().itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
                .sql("INSERT INTO person (first_name, last_name) VALUES (:firstName, :lastName)").dataSource(dataSource).build();
    }

    @Bean
    public Job importUserJob(JobCompletionNotificationListener listener, Step step1) {
        return jobBuilderFactory.get("importUserJob").incrementer(new RunIdIncrementer()).listener(listener).flow(step1).end().build();
    }

   @Bean
public Step step1(JdbcBatchItemWriter<Person> writer) {
    return stepBuilderFactory.get("step1").<Person, Person> chunk(3).reader(reader()).processor(processor()).writer(writer).faultTolerant().skipLimit(2)
            .skip(Exception.class).build();
}
   }

我试图通过在我的项目处理器中为一条记录手动抛出异常来模拟异常

public class PersonItemProcessor implements ItemProcessor<Person, Person> {

    private static final Logger log = LoggerFactory.getLogger(PersonItemProcessor.class);

    @Override
    public Person process(final Person person) throws Exception {
        final String firstName = person.getFirstName().toUpperCase();
        final String lastName = person.getLastName().toUpperCase();

        final Person transformedPerson = new Person(firstName, lastName);

        log.info("Converting (" + person + ") into (" + transformedPerson + ")");
        if (person.getLastName().equals("Doem"))
            throw new Exception("DOOM");
        return transformedPerson;
    }
}

现在根据跳过限制,当异常被抛出时,项目处理器将重新处理块并跳过抛出错误的项目,项目写入也将所有记录插入数据库,除了一条异常记录。

这一切都很好,因为我的处理器,它只是转换为大写字母名称,它可以运行很多次,但影响很大。

其他的选择是什么?

共有1个答案

有品
2023-03-14

根据您的描述,您的项目处理器不是幂等的。但是,文档中的容错部分指出,当使用容错步骤时,项处理器应该是幂等的。以下是节选:

如果一个步骤被配置为容错(通常通过使用跳过或重试处理),那么使用的任何ItemProcessor都应该以幂等的方式实现。

 类似资料:
  • 我对Spring批处理跳过逻辑有一些问题。我已经配置了一个作业的步骤来跳过两个异常(SQLIntegrityConstraintViolation异常和乐观锁定失败异常): 但当作业运行时,由于我将其配置为跳过的异常,作业以未知状态完成: 我做错什么了吗?我希望这一步跳过负责抛出其中一个异常的项,并继续处理,以便以完成状态结束。

  • 我是Spring批处理的新手,我只想问如何从多行结果集中检索数据。我有以下场景: > 有两个不同的表说员工 使用时,我只能创建一个工资单子级,但该表可能有多个子级。请帮助...

  • 我们使用Spring Batch进行一些处理,通过Reader读取一些ID,我们希望通过处理器将它们处理为“块”,然后写入多个文件。但是处理器接口一次只允许处理一个项目,我们需要进行批量处理,因为处理器依赖于第三方,不能为每个项目调用服务。 我看到我们可以为“块”中涉及的所有读取器-处理器-写入器创建包装器,以处理列表<>并委托给一些具体的读取器/处理器/写入器。但这对我来说并不是件好事。像这样:

  • 我是一个初学者,刚刚开始学习Spring Batch。我在这里按照这个教程创建了一个helloworld示例。当我按照教程操作时,我在尝试将导入java类时遇到了一个问题。因此我在网上搜索,发现我需要在build.gradle.中添加一些东西。问题是,即使我在build.gradle中添加了依赖项,我仍然有导入的错误消息。我正在使用EclipseJavaEE IDE 4.5.0(Mars)来完成这

  • 当我使用Spring批处理管理运行长时间运行的批处理作业的多个实例时,它会在达到jobLauncher线程池任务执行程序池大小后阻止其他作业运行。但是从cron中提取多个工作似乎效果不错。下面是作业启动器配置。 Spring批处理管理员Restful API是否使用不同于xml配置中指定的作业启动器?

  • 我在我的项目中集成了Spring Batch,我在运行JobLauncher时遇到了问题。 在我的类JobLauncher我有这个: 对于配置,我使用XML配置: 配置批处理。xml: 在作业配置中。我有: 当我在类JobLauncher中调试时,它会在jobLuancher中停止。运行,我也不例外,似乎SpringBatch无法识别reader和whriter!!有什么建议吗?