JSR 352:如何从分区步骤的每个分区的写入器收集数据?

Faz*_*ain 4 java-batch jsr352

因此,我在写入数据库的步骤中有 2 个分区。我想记录每个分区写入的行数,得到总和,打印到日志中;

我正在考虑static在编写器中使用变量并使用步骤上下文/作业上下文将其放入afterStep()步骤侦听器中。然而,当我尝试时,我得到了null。我能够从close()Reader 中获取这些值。

这是正确的做法吗?或者我应该使用分区收集器/减速器/分析器?

我在 Websphere Liberty 中使用 java 批处理。我正在 Eclipse 中开发。

Min*_*ang 5

我正在考虑在 Writer 中使用静态变量,并使用 Step Context/Job Context 将其获取到 Step Listener 的 afterStep() 中。然而,当我尝试它时,我得到了空。

ItemWriter此时可能已经被销毁,但我不确定。

这是正确的做法吗?

是的,应该足够好了。但是,您需要确保所有分区共享总行数,因为批处理运行时为每个分区维护一个StepContext克隆。你应该使用JobContext.

我认为使用PartitionCollector和PartitionAnalyzer也是一个不错的选择。接口PartitionCollector有一个方法collectPartitionData()来收集来自其分区的数据。收集后,批处理运行时会将这些数据传递给PartitionAnalyzer来分析数据。请注意,有

  • 每步 N 个 PartitionCollector(每个分区 1 个)
  • 每步 N 个 StepContext(每个分区 1 个)
  • 每步 1 个分区分析器

写入的记录可以通过StepContext传递transientUserData。由于StepContext是为其自己的步骤分区保留的,因此临时用户数据不会被其他分区覆盖。


这是实现:

我的项目作家:

@Inject
private StepContext stepContext;

@Override
public void writeItems(List<Object> items) throws Exception {
    // ...
    Object userData = stepContext.getTransientUserData();
    stepContext.setTransientUserData(partRowCount);
}
Run Code Online (Sandbox Code Playgroud)

我的分区收集器

@Inject
private StepContext stepContext;

@Override
public Serializable collectPartitionData() throws Exception {

    // get transient user data
    Object userData = stepContext.getTransientUserData();
    int partRowCount = userData != null ? (int) userData : 0;
    return partRowCount;
}
Run Code Online (Sandbox Code Playgroud)

我的分区分析器

private int rowCount = 0;

@Override
public void analyzeCollectorData(Serializable fromCollector) throws Exception {
    rowCount += (int) fromCollector;
    System.out.printf("%d rows processed (all partitions).%n", rowCount);
}
Run Code Online (Sandbox Code Playgroud)

参考:JSR352 v1.0 Final Release.pdf