【问题标题】:Chunk reading in Spring Batch - not only chunk writingSpring Batch 中的块读取 - 不仅是块写入
【发布时间】:2012-12-07 20:23:46
【问题描述】:

我的假设

在我的理解中,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 中是否有任何现有功能?

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

我很乐意接受任何最佳做法。在此先感谢:-)

【问题讨论】:

    标签: spring-batch chunking


    【解决方案1】:

    这是 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 是块中读取的项目的缓冲区,框架尚未请求。

    【讨论】:

      【解决方案2】:

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

      面向块的处理是指

      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。最后,您的 Writer 将获得一个List of 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);
      

      【讨论】:

      • 感谢您详尽的回答。我仍然不得不怀疑项目列表是否有效。那么如何利用 Spring Batch 的回退机制呢?如果在处理一个块的过程中出现异常,那么 Spring Batch 将切换到单个处理。这将不再起作用。我仍然认为 Spring Batch 在这里缺少一个功能。
      • 从阅读器返回一个列表也有一个缺点,即您不能通过在处理器中返回 null 来轻松过滤项目(因此它确实算作过滤),并且像 readCount、writeCount、 filterCount 等不代表项目的数量,而是项目列表的数量。
      猜你喜欢
      • 2023-03-25
      • 1970-01-01
      • 2019-10-29
      • 1970-01-01
      • 1970-01-01
      • 2019-01-09
      • 1970-01-01
      • 2012-06-21
      • 1970-01-01
      相关资源
      最近更新 更多