7

我的假设

据我了解,Spring Batch 中的“面向块的处理”帮助我在单个事务中有效地处理多个项目。这包括有效使用来自外部系统的接口。由于外部通信包括开销,它也应该是有限的和面向块的。这就是为什么我们有提交级别的ItemWriter. 所以我不明白的是,为什么ItemReader仍然需要逐项阅读?为什么我也不能读取块?

问题描述

在我的步骤中,读者必须调用网络服务。并且作者会将这些信息发送到另一个网络服务。这就是为什么我不想尽可能少地打电话。

的界面ItemWriter是面向块的 - 正如你肯定知道的那样:

public abstract void write(List<? extends T> paramList) throws Exception;

ItemReader不是:

public abstract T read() throws Exception;

作为一种解决方法,我实现了一个ChunkBufferingItemReader,它读取项目列表,存储它们并在read()调用其方法时一个接一个地返回项目。

但是现在当涉及到异常处理和重新启动作业时,这种方法变得混乱。我觉得我在这里工作,框架应该为我做的。

问题

所以我错过了什么吗?我刚刚忽略的 Spring Batch 中是否有任何现有功能?

另一篇文章中,建议将返回类型更改ItemReader为 a List。但是我ItemProcessor将不得不从单个输入发出多个输出。这是正确的方法吗?

我很乐意接受任何最佳实践。提前致谢 :-)

4

2 回答 2

4

这是 read() 接口方法的实现草案。

public T read() throws Exception {
    while (this.items.isEmpty()) {
        final List<T> newItems = readChunk();
        if (newItems == null) {
            return null;
        }
        this.items.addAll(newItems);
    }
    return this.items.pop();
}

请注意,这items是块中读取的项目的缓冲区,框架尚未请求。

于 2014-02-20T19:22:04.723 回答
0

Spring Batch 使用“面向块”的处理方式。(不只是块读写,包括读、处理和写的全过程)

面向块的处理是指

  1. 使用 ItemReader(单项)读取项目
  2. 使用 ItemProcessor 对其进行处理,并汇总结果(结果列表一一更新)。
  3. 一旦达到提交间隔,就会使用 ItemWriter 写出整个聚合结果(结果列表),然后提交事务。

这是来自 SpringBatch 文档的代码表示

List items = new Arraylist();
for(int i = 0; i < commitInterval; i++){
    Object item = itemReader.read()
    Object processedItem = itemProcessor.process(item);
    items.add(processedItem);
}
itemWriter.write(items);

正如您所说,如果您需要您的读者返回多个项目,请将其设为List。如果你的处理器也返回一个List。最后,您的 Writer 将获得List 的 List

这是新案例的代码表示

List<List<Object>> resultList = new Arraylist<List<Object>>();
for(int i = 0; i < commitInterval; i++){
    List<Object> items = itemReader.read()
    List<Object> processedItems = itemProcessor.process(items);
    resultList.add(processedItems);
}
itemWriter.write(resultList);
于 2013-02-18T16:55:39.983 回答