【问题标题】:Spring-batch step not re-executed (cache)Spring-batch 步骤未重新执行(缓存)
【发布时间】:2021-10-26 12:46:51
【问题描述】:

我正在做一个包含 Spring 批处理的项目,在复制代码 sn-ps 之前,我将简单地总结一下这项工作是如何使用 cron 工作的。

  1. cron 在我的项目上调用了一个 rest API (@PostMapping("/jobs/external/{jobName}"))
  2. 在 post 方法中,我得到工作并执行它。
  3. 在每次执行中,我应该运行一个步骤。
  4. 该步骤包含一个读取器(对弹性 API 的外部 rest 调用以获取文档)和一个处理器。

现在我的问题是:在catalina.out 中,我可以按照我的 cron 中的配置每 10 分钟查看一次来自 cron 的其余调用。但是,该步骤似乎不是每 10 分钟调用一次弹性,批处理始终具有相同的数据集,在 tomcat 重新启动期间调用批处理时会获取一次。

工作休息接口:

@PostMapping("/jobs/external/{jobName}")
@Timed
public ResponseEntity start(@PathVariable String jobName) throws BatchException {
    log.info("LAUNCHING JOB FROM EXTERNAL : {}, timestamp : {}", jobName, Instant.now().toString());
    try {
        Job job = jobRegistry.getJob(jobName);
        JobParametersBuilder builder = new JobParametersBuilder();
        builder.addDate("date", new Date());
        return Optional.of(jobLauncher.run(job, builder.toJobParameters()))
            .map(BatchExecutionVM::new)
            .map(exec -> ResponseEntity
                .ok()
                .headers(HeaderUtil.createAlert("jobManagement.started", jobName))
                .body(exec))
            .orElseGet(() -> ResponseEntity.badRequest().build());
    } catch (NoSuchJobException aEx) {
        log.warn(JOB_NOT_FOUND, aEx);
        throw new BatchException();
    } catch (JobInstanceAlreadyCompleteException | JobExecutionAlreadyRunningException | JobRestartException aEx) {
        log.warn("Job execution error.", aEx);
        throw new BatchException();
    } catch (JobParametersInvalidException aEx) {
        log.warn("Job parameters are invalid.", aEx);
        throw new BatchException();
    }
}

工作配置:

@Bean
public Job usualJob() {
    return jobBuilderFactory
        .get("usualJob")
        .incrementer(new SimpleJobIncrementer())
        .flow(readUsualStep())
        .end()
        .build();
}

@Bean
public Step readUsualStep() {
    // TODO: simplifier on n'a pas besoin de chunk
    return stepBuilderFactory.get("readUsualStep")
        .allowStartIfComplete(true)
        .<AlertDocument, Void>chunk(25)
        .readerIsTransactionalQueue()
        .reader(rowItemReader())
        .processor(rowItemProcessor())
        .build();
}
@Bean
public ItemReader<AlertDocument> rowItemReader() {
    return new UsualItemReader(usualService.getLastAlerts());
}
@Bean
public UsualMapRowProcessor rowItemProcessor() {
    return new UsualMapRowProcessor();
}

我不知道为什么 usualService.getLastAlerts() 只被调用一次,而不是每 10 分钟调用一次。

【问题讨论】:

  • 因为你的 rowItemReader bean 是一个单例,而不是工作或步骤范围。
  • 很抱歉,我真的不掌握春季批次。一个单例对我来说意味着一个实例,但是这个实例应该每 10 分钟调用一次吗?
  • 没有。此实例将创建一次,每 10 分钟重复使用一次。配置不是每 10 分钟加载一次。因此,您需要将作业的 bean 步骤设置为范围,以便每次执行时都会重新创建该 bean,从而执行请求。
  • 谢谢你 M. Deinum,我用 @StepScope 注释了我的 steap bean,它起作用了。

标签: spring spring-batch


【解决方案1】:

感谢 M. Deinum,这基本上是解决方案:

    @Bean
@StepScope
public ItemReader<AlertDocument> rowItemReader() {
    return new UsualItemReader(usualService.getLastAlerts());
}

使用 stepScope 注释对 step bean 进行注释将使其每一步都重新实例化。

【讨论】:

    猜你喜欢
    • 2020-12-20
    • 2022-01-07
    • 2019-01-05
    • 2015-08-19
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多