我试图在逻辑上划分弹簧批处理作业的特定要求。 我们有一个Process表,它将为我提供准备好处理的记录。 进程表中的每条记录都可以由process_id唯一标识 对于每个process_id,我将生成一个可能有数百万行的Excel报告,即我们将有多个excel文件作为作业的输出。
我的计划是
在内存管理方面,上述方法对我来说并不好听 由于要写入的记录是在处理器中生成的(而不是从阅读器中获取,读者只是提供记录ID),所以只有在完成所有处理后,我才能提交。 如果它是多个线程,那么在编写它们之前,我们将在内存中包含太多这些大对象。
我看到的挑战是我读了一条记录但写了多条记录。因此,提交间隔= 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写入文件