查找 spring 个已存在 X 天的批处理实例

Finding spring batch instances which are X days old

目前我已经重新启动 spring-batch 作业,每小时 运行 并通过 JobExplorer 检查数据库以查找失败的作业实例,它会为作业选择最新的作业实例失败并重新启动最新的执行。这工作正常,但我们现在有新的请求,不仅要重启最新的实例,还要重启 X 天 window 内的所有实例,我们应该从最旧的实例开始重新启动一个实例,直到它脱离这个 window.

示例:

我在考虑两个方案:

  1. 使用 JobExplorer 以及 List<JobInstance> getJobInstances(String jobName, int start, int count);int getJobInstanceCount(String jobName) throws NoSuchJobException; 的组合,并通过检查开始时间遍历列表以找到我要查找的内容
  2. 扩展 JdbcJobInstanceDao 并编写我自己的针对 JOB_INSTANCE 的查询 table 加入 JOB_EXECUTION 并使用

是否有更好的方法来获取某个作业的所有失败作业实例,这些实例最多存在 3 天,并将它们排在最前面?

如果没有更好的方法,您如何看待选项1和2?

我最终按照 Michael Minella 的建议编写了自己的 JobInstanceDao。我只在重新启动作业中需要它,所以我没有扩展 spring 第一批,但我使用 spring 第一批作为示例。如果有人需要,这里是实现:

package com.custom.package;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.joda.time.DateTime;
import org.springframework.batch.core.JobInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

@Component
public class CustomJobInstanceDao {

    public static final String BATCH_TABLE_PREFIX = "BATCH";

    private static final String GET_JOBS_WITH_STATUS_AFTER_DATE = "SELECT ji.JOB_INSTANCE_ID, ji.JOB_NAME FROM %PREFIX%_JOB_EXECUTION je LEFT JOIN %PREFIX%_JOB_INSTANCE ji "
            + " ON je.JOB_INSTANCE_ID = ji.JOB_INSTANCE_ID WHERE ji.JOB_NAME = ? AND je.STATUS = ? AND je.START_TIME > ? GROUP BY  je.JOB_INSTANCE_ID";

    private static final String GET_RUNNING_JOBS_AFTER_DATE = "SELECT ji.JOB_INSTANCE_ID, ji.JOB_NAME FROM %PREFIX%_JOB_EXECUTION je LEFT JOIN %PREFIX%_JOB_INSTANCE ji "
            + " ON je.JOB_INSTANCE_ID = ji.JOB_INSTANCE_ID WHERE ji.JOB_NAME = ? AND je.END_TIME is NULL AND je.START_TIME > ? GROUP BY  je.JOB_INSTANCE_ID";

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public List<JobInstance> getJobInstancesWithStatusAfterStartDate(final String jobName, final String status,
            final DateTime afterStartTime) {

        return jdbcTemplate.query(getQuery(GET_JOBS_WITH_STATUS_AFTER_DATE), new Object[] {jobName, status,
                afterStartTime.toDate()}, new JobInstanceRowMapper());
    }

    public List<JobInstance> getRunningJobInstancesAfterStartDate(final String jobName, final DateTime afterStartTime) {

        return jdbcTemplate.query(getQuery(GET_RUNNING_JOBS_AFTER_DATE),
                new Object[] {jobName, afterStartTime.toDate()}, new JobInstanceRowMapper());
    }

    private String getQuery(final String base) {
        return StringUtils.replace(base, "%PREFIX%", BATCH_TABLE_PREFIX);
    }

    private final class JobInstanceRowMapper implements ParameterizedRowMapper<JobInstance> {

        public JobInstanceRowMapper() {
        }

        @Override
        public JobInstance mapRow(final ResultSet rs, final int rowNum) throws SQLException {
            final JobInstance jobInstance = new JobInstance(rs.getLong(1), rs.getString(2));
            // should always be at version=0 because they never get updated
            jobInstance.incrementVersion();
            return jobInstance;
        }
    }

}