Spring Batch - 读取一条记录在多线程步骤中写入多条记录

时间:2014-11-18 03:33:46

标签: spring batch-processing spring-batch

我试图在逻辑上划分弹簧批处理作业的特定要求。 我们有一个Process表,它将为我提供准备好处理的记录。 进程表中的每条记录都可以由process_id唯一标识 对于每个process_id,我将生成一个可能有数百万行的Excel报告,即我们将有多个excel文件作为作业的输出。

我的计划是

  1. 使用多线程步骤,以便每个线程读取一条记录 - 在处理器中生成多条记录 - 将生成的记录写入单独的Excel文件中。
  2. 使用同步阅读器从进程表中读取。
  3. 在处理器中使用读取器中返回的记录来查询DB(涉及多个连接)并形成一个复合对象。
  4. 将复合对象写入自定义编写器
  5. 中的文件

    在内存管理方面,上述方法对我来说并不好听 由于要写入的记录是在处理器中生成的(而不是从阅读器中获取,读者只是提供记录ID),所以只有在完成所有处理后,我才能提交。 如果它是多个线程,那么在编写它们之前,我们将在内存中包含太多这些大对象。

    我看到的挑战是我读了一条记录但写了多条记录。因此,提交间隔= 1意味着对于每个读取和处理的记录,将有一次写入 由于处理器生成了数百万条记录,因此我只能在整个处理完成后提交。这里的基本目标是并行生成多个文件。 有没有更好的方法来设计这个批处理作业?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

您可以使用基于process_id的分区程序(首先获取所有唯一的processIds并在您的自定义分区程序中)并激活多个查询(尽管大多数DBA并不同意这一点,并且可能会遇到临时空间db)在读者中

这是一个原型

<batch:step id="step1.slave">
    <batch:tasklet>
        <batch:chunk reader="jdbcCursorItemReader" writer="csvItemWriter" commit-interval="${app.max_number_of_rows}">
        </batch:chunk>
    </batch:tasklet>
</batch:step>

<bean id="jdbcCursorItemReader"
        class="org.springframework.batch.item.database.JdbcCursorItemReader">
        <property name="dataSource" ref="dataSource" />
        <property name="sql">
            <value>
                select *
                from blah blah
                where process_id=?
            </value>
        </property>
        <property name="preparedStatementSetter" ref="myPsSetter" />
</bean>

<bean id="myPsSetter" class="com.kp.swasthik.ps.BeamBalancePsSetter"
        scope="step">
        <property name="processId" value="#{stepExecutionContext['processId']}"></property>
</bean>

如何编写自定义分区程序,请参阅此link

如果您不想触发多个查询,可以使用单个ItemReader(虽然它不是多线程的)并使用复合ItemWriter写入文件