繁体   English   中英

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

[英]Accesing JobContext from a partitioned step in JSR 352

我正在尝试在批处理之间传递一个对象,但是在尝试从分区步骤(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,所以我不是把它作为答案。

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

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

stepCtx.setPersistentUserData(mySerializableData);

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

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

没有一种规范定义的方法来共享主线程的JobContext和分区级JobContext之间的临时用户数据。 这是一个可以理解的混淆点,但这确实是预期的设计。

在规范中提到了访问Context - Injection的唯一方法。 见第9.4.1段。

“9.4.1批量上下文

批处理上下文的批处理工件访问是使用标准的@Inject批注(javax.inject.Inject)进行注入。 注入批处理上下文的字段不能是静态的,也不能是最终的。

例如:

@Inject JobContext _jctxt;

@Inject StepContext _sctxt;

批处理运行时负责确保根据当前正在执行的作业或步骤注入正确的上下文对象。“

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM