在Spring Batch Step,Tasklet或Chunks之间做出决定

时间:2013-06-17 08:44:33

标签: spring-batch

我有一个直接的要求,其中,我需要读取项目列表(来自数据库)并需要处理这些项目,一旦处理完毕,就必须将其更新为数据库。

我正在考虑将Spring批量块与读取器,处理器和写入器一起使用。我的读者将从列表中一次返回一个项目并将其发送到处理器,一旦处理结束,它将返回到Writer更新数据库

我可能会稍后对它进行多线程处理,并在这些方法中花费一些同步费用。

我预见到一些问题。

  1. 要处理的项目数量可能更多。可能是10,000s甚至更多。
  2. 处理器需要进行一些逻辑计算。因此,一次处理1个项目。即使它是10个线程的多线程,也不确定性能。
  3. Writer可以更新该处理项目的数据库中的结果。不确定如何进行批量更新,因为它始终只处理了1个项目并准备就绪。
  4. 这种方法对于这种用例是否正确或者可以做得更好? 有没有其他方法可以在一次读取,处理器和放大器处理时处理一堆物品。作家?如果是这样,我是否需要创建一些机制,我从列表中提取10个项目并将其提供给处理器? 似乎编写器会更新每个记录,只有当编写器收到一堆处理过的项目时,批量更新才有意义。有什么建议吗?

    请在此设计上注明一些亮点以获得更好的性能。

    谢谢,

1 个答案:

答案 0 :(得分:14)

Spring Batch是您完成所需工作的完美工具。

面向块的步骤允许您使用commit-interval属性配置要读取/处理/写入的项目数。

        <batch:step id="step1" next="step2">
        <batch:tasklet transaction-manager="transactionManager" start-limit="100">
            <batch:chunk reader="myReader" processor="myProcessor" writer="MyWriter" commit-interval="800" />
            <batch:listeners>
                <batch:listener ref="myListener" />
            </batch:listeners>
        </batch:tasklet>
    </batch:step>

假设您的读者将调用一条返回10 000条记录的SELECT语句。并设置commit-interval = 500。

MyReader将调用read()方法500次。假设实际上,读者实现可能实际上从resultSet中删除了项目。对于每次调用read(),它还将调用MyProcessor的process()方法。

但是在达到commit-interval之前它不会调用MyWriter的write()方法。

如果你看一下ItemWriter接口的定义:

public interface ItemWriter<T> {

/**
 * Process the supplied data element. Will not be called with any null items
 * in normal operation.
 * 
 * @throws Exception if there are errors. The framework will catch the
 * exception and convert or rethrow it as appropriate.
 */
void write(List<? extends T> items) throws Exception;

}

您会看到写入会收到项目列表。此列表将是您的提交间隔的大小(如果达到结束,则为更小)

顺便说一句,1万条记录什么都没有。如果必须处理数百万条记录,可以考虑多线程。但即便如此,只要玩一下commit-interval值的最佳位置就足够了。

希望有所帮助