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

Spring Batch查找开始作业执行

康恩
2023-03-14

我有一份Spring批量申请,只有一份工作。作业执行顺序对我来说至关重要,因此JobLauncher配置为单线程作业池。换句话说,如果触发的执行很少,则一个执行正在运行,另一个将在队列中等待。

作业执行表将如下所示:

        ╒═════╤═════════════════════╤════════════╤════════════╤═════╕
        │ ... │ START_TIME          │ END_TIME   │ STATUS     │ ... │
        ╞═════╪═════════════════════╪════════════╪════════════╪═════╡
        │ ... │ 2019-07-11 11:03:08 │ NULL       │ STARTED    │ ... │
        ├─────┼─────────────────────┼────────────┼────────────┼─────┤
        │ ... │ NULL                │ NULL       │ STARTING   │ ... │
        └─────┴─────────────────────┴────────────┴────────────┴─────┘

如果JVM崩溃,我需要从该状态恢复并进行一些审计,因此我需要找到所有已启动已启动执行。

找到第一个不是问题,我可以用JobExplorer做到:

Set<JobExecution> executions = jobExplorer.findRunningJobExecutions("jobName");

它只会给我START执行当前START\u时间。但是如何找到所有开始执行的

到目前为止,我找到的唯一方法是迭代作业实例,然后为每个实例找到开始执行的。类似这样:

        jobExplorer.findJobInstancesByJobName("jobName", 0, 100)
                .forEach(jobInstance -> {
                    jobExplorer.getJobExecutions(jobInstance)
                            .stream()
                            .filter(execution -> STARTING.equals(execution.getStatus()))
                            .forEach(execution -> {
                                // do the job
                            });
                });

这里的问题是,你总是做一个有限制的完整扫描(我指定了100)。有没有更好的方法,比如jobExplorer。在Spring批处理中查找启动作业执行(“作业名称”)


共有1个答案

章承基
2023-03-14

我没有看到任何公共API可以按状态执行作业。您可以做的是(在伪代码中):

JobInstance jobInstance = jobInstanceDao.getJobInstance(jobName, jobParameters);
List<JobExecution> jobExecutions =  jobExplorer.findJobExecutions(jobInstance);
// iterate over job execution and filter by status

这将避免加载所有作业实例(一次加载100个)。

这就是说,我认为JobRepository界面可以添加一个方法,通过名称和参数(类似于isJobInstanceExists)获取作业实例,以避免使用jobInstanceDao,如我之前的代码片段所示。

编辑:

我猜您最初的要求是将作业执行标记为无法重新启动。为此,您可以手动将作业执行的状态(以及它的步骤执行)更改为FAILED,并将其END_TIME设置为非空值(此处解释:https://docs.spring.io/spring-batch/4.1.x/reference/html/job.html#aborting-a-job)。这样,您就可以重新启动失败的执行。

 类似资料:
  • 示例: 对于文档: video1title=大海是蓝色的 video2title=狂野的大海 video3title=狂野的大海 video4title=海边随便什么 null null 现在,AFAIKS,没有真正的方法告诉Lucene“找到word1和word2等位于位置1和2和3等的文档。” 有一些“变通办法”可以模拟这种行为: > 对字段进行两次索引。在中,您将单词标记化(可能使用),在中

  • 用例:步骤1:ItemReader:从数据库中读取1000个ItemProcessor块中的数据:处理这些数据。ItemWriter:将数据写入地图,以便下一步使用 步骤2:ItemReader:读取地图ItemProcessor:处理地图数据并获取新对象。ItemWriter:将新的进程对象持久化到数据库中。 现在我希望Map在整个作业中保持不变,目前我已经为Map创建了一个不同的POJO类,并

  • 问题内容: 我正在使用Jenkins DSL插件自动为git项目的所有分支创建构建作业。DSL插件由Web挂钩触发,以便在创建新分支后立即运行。每个分支生成的生成作业也被配置为由Web挂钩触发。 当前设置的问题是,仅在第二次提交后才执行构建。第一次提交将触发Jenkins DSL插件来创建相应的Jenkins作业,然后第二次提交将触发新创建的作业。 有什么方法可以通过DSL插件创建Jenkins作

  • 公共静态空main(String[]args)抛出异常{ 最终StreamExecutionEnvironment env=StreamExecutionEnvironment。getExecutionEnvironment();环境。setRuntimeMode(RuntimeExecutionMode.BATCH); } 哪个节点执行逻辑,例如上面的ftpUri定义。 我尝试用断点将调试器附加

  • 问题: 我正在为我的一个spring批处理作业方法编写单元测试。我使用mockito来模拟我的批处理作业依赖关系。在jobExecution发挥作用之前,一切都很好。我要测试的方法调用了jobExecution变量,但它给了我NPE(NullPointerException)并且我没有成功地用mockito模拟它。 删除此currentJobExecution时 从我要测试的方法,然后测试成功完成

  • 我已经将quartz配置为在集群中工作这里是我的简单quartz配置 我有两个节点正在执行我的作业,但是,当我计划每秒运行某个任务时,我可以看到它只在Node1上执行。如果我暂停node1上的调度程序,任务将移动到node2,并且即使当node1再次联机时也会坚持它。我如何可能使执行在节点之间均匀地偏离? 谢谢