3

我是 Java Batch 新手。我在 WebSphere Liberty 17.0.0.4 上部署了一个包含 JobListener 的简单批处理作业(请注意,我使用的是 IBM 的 JSR-352 实现,而不是 Spring Batch)。批处理作业本身按预期运行:它读取输入文件,进行简单的数据转换,然后写入数据库。但是在成功执行的 JobListener 的 afterJob() 方法中,我看到批处理状态为 STARTED,退出状态为 null。(这些值与我在 beforeJob() 方法中看到的值相同)。我希望 afterJob() 看到 COMPLETED 的状态,除非有例外。

afterJob() 记录的执行 ID 与 JobOperator.start() 在我开始作业时返回的值相同,所以我知道我得到了正确作业执行的状态。

我找不到任何获取批处理状态的 JobListener 示例,因此我的 JSL 中可能有一个简单的错误,或者我错误地获取了批处理状态。或者我是否需要在步骤的实施中明确设置状态?对于设置和获取作业执行的最终批处理状态和退出状态的正确技术,我将不胜感激。

这是JSL:

<job ...>
    <properties>...</properties>

    <listeners>
        <listener ref="jobCompletionNotificationListener"/>
    </listeners>

    <flow id="flow1">
        <step id="step1">...</step>
    </flow>
</job>

这是batch.xml中监听器的定义:

<ref id="jobCompletionNotificationListener"
     class="com.llbean.batch.translatepersonnames.jobs.JobCompletedListener"/>    

这是 JobListener 的实现:

@Dependent
@Named("jobCompletedListener")
public class JobCompletedListener implements JobListener {
    ...
    @Inject
    private JobContext jobContext;

    @Override
    public void afterJob() {
        long executionId = jobContext.getExecutionId();
        JobExecution jobExecution = BatchRuntime.getJobOperator().getJobExecution(executionId);
        BatchStatus batchStatus = jobExecution.getBatchStatus();
        String exitStatus = jobExecution.getExitStatus();
        logger.info("afterJob(): Job id " + executionId + " batch status = " + batchStatus + 
                ", exit status = " + exitStatus);
        ...
    }
}

我尝试在 JSL 中添加<end on="*" exit-status="COMPLETED"/>and <job><flow>但没有效果或导致状态为 FAILED。

4

2 回答 2

4

好问题。让我对@cheng 的回答补充几点。

首先,要理解为什么我们以这种方式实现它,请考虑 JobListener 抛出异常的情况。那应该让工作失败吗?在 Liberty 中,我们决定应该这样做。但是,如果工作已经有了COMPLETED状态,那么,这意味着它已经……完成了,并且不应该在那个时候失败。

所以afterJob()实际上更像是“工作结束”(或者您可以将其视为“工作步骤之后”)。

其次,问这个问题的一个原因是因为你想知道,在afterJob()方法中,作业是否成功执行。

好吧,至少在 Liberty 实现中(我为 IBM 工作),您确实可以看到这一点。先前的失败将BatchStatus设置为,FAILED而成功(到目前为止)执行的状态仍为STARTED

(对于它的价值,这是我们意识到可以在 1.0 规范工作的后期使用更多关注和标准化的领域,我希望我们能在未来解决更多问题。)

如果它有帮助并且您感兴趣,您可以在此处查看WorkUnitThreadControllerImpl.endOfWorkUnit导致调用并包括调用的流程中的基本逻辑。

于 2018-01-18T02:26:29.807 回答
2

这是因为作业侦听器的afterJob方法是作业执行的一部分。因此,当您调用getBatchStatus()内部afterJob()方法时,作业执行仍在进行中,尚未完成,因此批处理状态STARTED

于 2018-01-18T01:28:01.677 回答