SimpleAsyncTaskExecutor trying to read record after completion of processing

空扰寡人 提交于 2019-12-11 13:24:27

问题


In my spring batch project, I need to read from a list of rows from a table, create a chunk of 4 and process and then write to another table. I have implemented SimpleAsyncTaskExecutor to allow for parallel processing of chunks, but I find that after all records in the recordset are processed, Spring Batch is trying to continue reading next lot of result and failing. After it exceeds the skip level, it obviously aborts the job.

My query is - why will be the batch continue to look for next record after completion of processing all records in the set?

Error I get at the end is:

org.springframework.batch.core.step.item.FaultTolerantChunkProvider - Skipping failed input org.springframework.jdbc.UncategorizedSQLException: Attempt to process next row failed; uncategorized SQLException for SQL

Below is my batch xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/batch"
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <beans:import resource="../launch-context.xml" />

    <beans:bean id="wsStudentItemReader"
        class="org.springframework.batch.item.database.JdbcCursorItemReader"    
        scope="step">
        <beans:property name="dataSource" ref="rptDS" />
        <beans:property name="sql"
            value="SELECT * FROM STUDENTS WHERE BATCH_ID=?" />
        <beans:property name="preparedStatementSetter">
            <beans:bean class="com.test.BatchDtSetter"
                autowire="byName">
                <beans:property name="batchId" value="#{jobParameters[batchId]}" /> 
            </beans:bean>
        </beans:property>
        <beans:property name="rowMapper" ref="wsRowMapper" />
    </beans:bean>


 <beans:bean id="outputWriter"
        class="org.springframework.batch.item.support.ClassifierCompositeItemWriter">
        <beans:property name="classifier" ref="writerClassifier" >      
        </beans:property>       
 </beans:bean>  

<beans:bean id="writerClassifier"
    class="com.test.WriterClassifier">
    <beans:property name="codeFailWriter" ref="failJdbcBatchItemWriter" />
    <beans:property name="codePassWriter" ref="passJdbcBatchItemWriter"></beans:property>
</beans:bean>

    <beans:bean id="failJdbcBatchItemWriter"
        class="org.springframework.batch.item.database.JdbcBatchItemWriter">
        <beans:property name="dataSource" ref="rptDS" />
        <beans:property name="sql"
            value="DELETE FROM STUDENTS WHERE BATCH_ID=?" />
        <beans:property name="itemPreparedStatementSetter" ref="FailStatusSetter" />
    </beans:bean>

<beans:bean id="FailStatusSetter" class="com.test.FailStatusSetter" />

    <beans:bean id="passJdbcBatchItemWriter"
        class="com.test.PassBatchItemWriter">
    </beans:bean>

    <beans:bean id="WSListnr"
        class="com.test.WSBatchListnr">
        <beans:property name="dataSource" ref="rptDS" />
    </beans:bean>


    <beans:bean id="wsRowMapper" class="com.test.WSReqMapper" />
    <beans:bean id="wsReqPrcsr" 
         class="com.test.WSReqProc">
         <beans:property name="dataSource" ref="rptDS" />
    </beans:bean>
    <beans:bean id="wsReqPrepStmtSetter" class="com.test.wsStudentSetter" />

    <step id="initiateStep">
        <tasklet ref="initiateStepTask" />
    </step>
    <step id="wsStudentGenStep">
        <tasklet task-executor="taskExecutor">
            <chunk reader="wsStudentItemReader" processor="wsReqPrcsr"
                writer="outputWriter" commit-interval="4" skip-limit="20">
                <skippable-exception-classes>
                    <include class="java.lang.Exception" />
                </skippable-exception-classes>
            </chunk>
            <listeners> 
                <listener ref="WSListnr" />
            </listeners>            
        </tasklet>
    </step>
    <job id="wsStudent">
        <step id="wsStudentFileGenIntialStep" parent="initiateStep"
            next="wsStudentFileGenStep" />
        <step id="wsStudentFileGenStep" parent="wsStudentGenStep" />
    </job>


    <beans:bean id="initiateStepTask" class="com.test.Initializer"
        scope="step">
    </beans:bean>

    <beans:bean id="taskExecutor"
       class="org.springframework.core.task.SimpleAsyncTaskExecutor">
       <beans:property name="concurrencyLimit" value="2"/>
   </beans:bean>

</beans:beans>

回答1:


The issue is resolved by using JdbcPagingItemReader. This reader will synchronize the reads and also requires data to be ordered by a specific column.



来源:https://stackoverflow.com/questions/15587166/simpleasynctaskexecutor-trying-to-read-record-after-completion-of-processing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!