Spring Batch:作业随机选择行数少于commit-interval的行

时间:2017-11-30 17:45:17

标签: spring-batch batch-processing

我遇到了Spring Batch的问题。我们在我们的工作中使用了一个任务执行器(simpleAsyncTaskExecutor)来处理两个并行步骤的流程。

在每个步骤中,任务执行器将读取器返回的每个数据块拆分到不同的线程(使用多线程步骤概念:请参阅https://docs.spring.io/spring-batch/trunk/reference/html/scalability.html

问题是我们的提交间隔很大(24,000),读取器返回的行数非常少(少于50行)但是编写器有时会收到多个块(例如一块30行和20行的一个块,但对于另一个运行,它可以是25行的块和25行的块或仅50行的一个块,它看起来是随机的)而它应该只接收一个50块的块任何运行的行(它不应该是随机的),因为它不会超过提交间隔。

我试图理解为什么这会在某些运行中随机发生。 如果有人在Spring Batch中知道这个问题,你能帮助我吗?

谢谢。

以下是我的工作配置(不包括我们的自定义编写者):

    <batch:job id="job">

             <batch:split id="split" task-executor="taskExecutor">  
                <batch:flow> 
                    <batch:step id="step1"> 
                        <batch:tasklet task-executor="taskExecutor" throttle-limit="4" >
                              <batch:chunk reader="reader1" writer="writer1" commit-interval="24000" />         
                        </batch:tasklet>
                    </batch:step>
                </batch:flow>
                <batch:flow> 

                    <batch:step id="step2">
                        <batch:tasklet task-executor="taskExecutor" throttle-limit="4" >
                              <batch:chunk reader="reader2" writer="writer2" commit-interval="24000" />         
                        </batch:tasklet>
                    </batch:step>
                </batch:flow>       
             </batch:split>
        </batch:job>

    <bean id="reader1" class="org.springframework.batch.item.database.JdbcPagingItemReader" scope="step">       
         <property name="dataSource" ref="postgresql_1" />                           

         <property name="queryProvider">            
             <bean class="org.springframework.batch.item.database.support.PostgresPagingQueryProvider">
                    <property name="selectClause" value="
                        SELECT name
                    " />
                    <property name="fromClause" value="
                        FROM database.people
                    " />
                    <property name="whereClause" value="
                        WHERE age > 30
                    " />
                    <property name="sortKeys">
                        <map>
                            <entry key="people_id" value="ASCENDING"/>
                        </map>
                    </property>             
            </bean>         
        </property>         
        <property name="saveState" value="false" />         
        <property name="rowMapper">             
             <bean class="fr.myapp.PeopleRowMapper" />      
        </property>     
    </bean>

        <bean id="reader2" class="org.springframework.batch.item.database.JdbcPagingItemReader" scope="step">       
       <property name="dataSource" ref="postgresql_1" />        
       <property name="queryProvider">          
               <bean class="org.springframework.batch.item.database.support.PostgresPagingQueryProvider">
                    <property name="selectClause" value="
                         SELECT product_name
                    " />
                    <property name="fromClause" value="
                        FROM database.products
                    " />
                    <property name="whereClause" value="
                        WHERE product_order_date <= '01/11/2017'
                    " />
                    <property name="sortKeys">
                        <map>
                            <entry key="product_id" value="ASCENDING"/>
                        </map>
                    </property>             
               </bean>      
           </property>      
       <property name="saveState" value="false" />      
       <property name="rowMapper">
                <bean class="fr.myapp.ProductsRowMapper" />
       </property>  
    </bean>
    <bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor">
          <property name="concurrencyLimit" value="8" />
    </bean>

1 个答案:

答案 0 :(得分:0)

在写入的挂起记录数达到commit-interval(或块大小)之前,不应调用writer的write()方法。之前唯一应该调用的是read()在读者中返回null,表示没有剩余结果。

当你看到较小的块是在工作的中间? RowMappers中是否有任何逻辑或者您省略的任何逻辑汇总了读取结果?