You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取已完成状态Spring Batch作业上一次执行的开始或结束日期

解决方案

可以直接通过Spring Batch框架自带的能力实现该需求,无需额外建表存储运行记录。

Spring Batch默认会维护一套以BATCH_为前缀的元数据表,其中BATCH_JOB_EXECUTION表会存储每一次作业执行的状态、开始时间、结束时间等全量信息,框架提供了JobExplorer工具类可以直接查询这些元数据,不需要自己额外维护运行记录。

实现步骤

  • 确认Spring Batch元数据表已初始化
    Spring Boot 2.x默认会根据spring.batch.jdbc.initialize-schema配置决定是否自动初始化元数据表,对非嵌入式持久化数据库需首次运行前将配置改为always,首次初始化完成后可改回never避免重复建表报错。
  • 在JobExecutionListener中注入JobExplorer查询最近成功执行时间
@Autowired
private JobExplorer jobExplorer;
// 替换为你自己的作业名称,和注册的Job Bean名称保持一致
private static final String TARGET_JOB_NAME = "yourCustomJobName";

@Override
public void beforeJob(JobExecution jobExecution) {
    Date lastRuntime = null;
    // 查询最近10条作业实例,可根据业务实际运行频率调整查询数量
    List<JobInstance> jobInstances = jobExplorer.findJobInstancesByName(TARGET_JOB_NAME, 0, 10);
    for (JobInstance instance : jobInstances) {
        List<JobExecution> executions = jobExplorer.getJobExecutions(instance);
        // 筛选成功完成的执行记录,按结束时间倒序取最新的一条
        Optional<JobExecution> lastSuccessExec = executions.stream()
                .filter(exec -> BatchStatus.COMPLETED.equals(exec.getStatus()))
                .max(Comparator.comparing(JobExecution::getEndTime));
        if (lastSuccessExec.isPresent()) {
            lastRuntime = lastSuccessExec.get().getEndTime();
            break;
        }
    }
    // 处理首次运行无历史记录的场景,可根据业务需求调整默认值
    if (lastRuntime == null) {
        lastRuntime = Date.from(LocalDate.of(2000,1,1)
                .atStartOfDay(ZoneId.systemDefault()).toInstant());
    }
    // 把时间参数写入作业执行上下文,后续步骤可直接读取
    jobExecution.getExecutionContext().put("lastruntime", lastRuntime);
}
  • 数据查询Reader中注入参数
    如果使用JdbcCursorItemReader/JdbcPagingItemReader,将Reader声明为@StepScope即可直接通过SpEL注入上下文中的参数:
@Bean
@StepScope
public JdbcCursorItemReader<YourEntity> yourDataReader(
        @Value("#{jobExecutionContext['lastruntime']}") Date lastRuntime,
        DataSource dataSource) {
    return new JdbcCursorItemReaderBuilder<YourEntity>()
            .dataSource(dataSource)
            .name("yourDataReader")
            .sql("select * from tablename where last_upd_dt >= ?")
            .preparedStatementSetter(ps -> ps.setDate(1, new java.sql.Date(lastRuntime.getTime())))
            .rowMapper(new BeanPropertyRowMapper<>(YourEntity.class))
            .build();
}

内容的提问来源于stack exchange,提问作者Andulos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 14:36:07