从JSR 352中的分区步骤访问JobContext

Pab*_*gas 5 java batch-processing glassfish-4

我正在尝试在批处理之间传递一个对象,但是在尝试从分区步骤(batchlet)访问jobContext时遇到了问题.

根据JSR 352规范

9.4.1.1批处理上下文生命周期和范围:批处理上下文具有线程关联,并且仅对在该特定线程上执行的批处理工件可见.超出范围时,批处理上下文注入字段可能为空.每种上下文类型都有一个不同的范围和生命周期,如下所示:1.JobContext每个作业执行一个JobContext.它存在于工作的生命中.并行执行的每个子线程都有一个独特的JobContext(例如,分区步骤). 2. StepContext每步执行一个StepContext.它存在于步骤的生命中.对于分区步骤,父步骤/线程有一个StepContext; 每个子线程都有一个独特的StepContext.

我的(失败)解决方案是使用JobContext.setTransientUserData,但由于分区步骤使用了不同的JobContext,因此无法获取TransientUserData.

有没有替代我正在尝试做的事情?使用PartitionMapper属性是不可能的,因为我需要将一个对象而不是一个字符串传递给每个分区.

要清楚,我需要这样做:

  1. NormalBatchlet - >保存要在下一步中使用的对象.
  2. PartitionedBatchlet - >在上一步中获取已保存的对象.此对象不是简单的String,因此使用PartitionMapper属性不是解决方案.

UPDATE

我现在使用带有HashMap的简单Singleton EJB在步骤之间存储对象,当作业完成时,我清除此映射以避免资源泄漏.

这是一种解决方法,因为我真的只想使用javax.batch包而不依赖于EJB,所以我不是把它作为答案.

小智 8

你可以尝试这样的东西,它应该符合当前的规范编程模型.

使用NormalBatchlet中的持久步骤数据存储第一步中的对象:

stepCtx.setPersistentUserData(mySerializableData);
Run Code Online (Sandbox Code Playgroud)

通过查找上一步,从分区的第一步检索数据:

Long execId = jobCtx.getExecutionId();

List<StepExecution> stepExecs = jobOperator.getStepExecutions(execID);

MyPersistentUserData myData;

for (StepExecution step : stepExecs) {
    if (step.getStepName().equals("somePreviousStepX") {
        myData = (MyPersistentUserData)step.getPersistentUserData();
    }
}

//use myData
Run Code Online (Sandbox Code Playgroud)