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



我有一个直接的要求,我需要读取项目列表(从DB),并需要处理项目,一旦处理,它必须更新到DB。

我正在考虑使用Spring批处理块与阅读器,处理器和写入器。我的阅读器将每次从列表中返回一个项目并将其发送到处理器,一旦处理结束,它返回到Writer,在那里它更新DB

我以后可能会在这些方法中多线程化一些同步成本。

在这里我预见到一些问题。

  1. 需要处理的项目数量可以更多。可能在10000个甚至更多。
  2. 在处理器中需要一些逻辑计算。因此,每次处理一个项目。即使是10个线程的多线程,也不确定性能。
  3. Writer可以在DB中更新该处理项的结果。不知道如何做批量更新,因为它总是只有一个项目处理和准备。

这种方法对于这种用例是正确的还是可以做更好的事情?是否有其他方法可以在一次调用阅读器、处理器时处理一堆项目?作家吗?如果是这样,我是否需要创建某种机制,从列表中提取10个项目并将其交给处理器?似乎写入器会在每个记录到来时更新它,批处理更新只有在写入器接收到一堆处理过的项目时才有意义。任何建议吗?

为了更好的表现,请在这个设计上添加一些亮点。

谢谢,

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()方法。

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

如果你看一下接口的定义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;
}

您可以看到write接收到一个项目列表。该列表将是提交间隔的大小(如果到达结束,则更小)

顺便说一句,10000条记录不算什么。如果必须处理数百万条记录,则可以考虑使用多线程。但即使这样,只要在提交间隔值的最佳位置上玩一玩,可能就足够了。

希望有所帮助

最新更新