春季批处理JdbcPagingItemReader作业将重新启动,并仅选择尚未选择的记录

时间:2018-10-17 13:59:17

标签: spring spring-boot spring-batch

如何通过可重启性实现容错的Spring批处理作业。我有一个包含 8个Milion 记录的表,然后使用 JdbcPagingItemReader 阅读器配置了一个作业以获取记录,并使用 AmqpItemWriter 将记录排队到 rabbitMQ 。 Challange是当我突然停止工作然后重新启动时,出现异常。预期的行为:

  1. 成功重启工作
  2. 从作业停止的ID开始读取表格

以下是配置:

@Bean
public JdbcPagingItemReader<NotificationRequest> notificationRequestJdbcPagingItemReader() {
    JdbcPagingItemReader<NotificationRequest> reader = new JdbcPagingItemReader<>();

    reader.setDataSource(this.dataSource);
    reader.setFetchSize(1000);
    reader.setRowMapper(new SmsSQLRowMapper());

    PostgresPagingQueryProvider queryProvider = new PostgresPagingQueryProvider();
    queryProvider.setSelectClause("subscriber_fk, event_time, record_flag, batch_date, message_type, cents_loanable, request_id, reason_code");
    queryProvider.setFromClause("from tbl_sms_tracker_new");

    Map<String, Order> sortKeys = new HashMap<>(1);

    sortKeys.put("request_id", Order.ASCENDING);

    queryProvider.setSortKeys(sortKeys);

    reader.setQueryProvider(queryProvider);

    return reader;
}

@Bean
public ItemWriter<NotificationRequest> notificationRequestAmqpItemWriter() {
    AmqpTemplate aTemplate = (AmqpTemplate) applicationContext.getBean("amqpTemplate");

    AmqpItemWriter<NotificationRequest> itemWriter = new AmqpItemWriter<>(aTemplate);

    return itemWriter;
}


@Bean
public Step step1() {
    return stepBuilderFactory.get("notificationStep1")
            .<NotificationRequest, NotificationRequest>chunk(1000)
            .reader(notificationRequestJdbcPagingItemReader())
            .writer(notificationRequestAmqpItemWriter())
            .faultTolerant()
            .build();
}


@Bean
public Job job() {
    return jobBuilderFactory.get("notificationJob")
            .start(step1())
            .build();
}

1 个答案:

答案 0 :(得分:0)

  

预期行为:

     
      
  1. 成功重启工作
  2.   

如果您突然停止工作(kill -9),则JobRepository无法知道您当前的工作状态,因为以前没有人告诉过您。您的工作可能不是,但仍处于STARTED状态(已被杀死)。这就是为什么在尝试重新启动终止的作业时会遇到异常的原因。您必须手动告诉作业存储库,您知道执行失败或应被视为中止。此处的更多详细信息:https://docs.spring.io/spring-batch/4.0.x/reference/html/job.html#aborting-a-job

  
      
  1. 从作业停止的ID开始读取表格
  2.   

突然停止作业时,当前执行上下文未正确保存到作业存储库中。在这种情况下,当您重新启动作业时,项目读取器将从最后一个“保存点”(即最后一个成功持久保存的执行上下文)中读取数据。但是,如果您优雅地停止工作,您提到的预期行为将得到兑现。