Spring批处理ItemProcessor处理项目的顺序

时间:2015-06-19 16:04:34

标签: spring spring-batch

这是我的弹簧配置文件。

<batch:job id="empTxnJob">
    <batch:step id="stepOne">
        <batch:partition partitioner="partitioner" step="worker" handler="partitionHandler" />
    </batch:step>
</batch:job>

<bean id="asyncTaskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor" />

<bean id="partitionHandler" class="org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler" scope="step">
    <property name="taskExecutor" ref="asyncTaskExecutor" />
    <property name="step" ref="worker" />
    <property name="gridSize" value="${batch.gridsize}" />
</bean>

<bean id="partitioner" class="com.spring.mybatch.EmpTxnRangePartitioner">
    <property name="empTxnDAO" ref="empTxnDAO" />
</bean>

<batch:step id="worker">
    <batch:tasklet transaction-manager="transactionManager">
        <batch:chunk reader="databaseReader" writer="databaseWriter" commit-interval="25" processor="itemProcessor">
        </batch:chunk>
    </batch:tasklet>
</batch:step>

<bean name="databaseReader" class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="step">
    <property name="dataSource" ref="dataSource" />
    <property name="sql">
        <value>
            <![CDATA[
                    select *
                    from 
                        emp_txn
                    where 
                        emp_txn_id >= #{stepExecutionContext['minValue']} 
                    and 
                        emp_txn_id <= #{stepExecutionContext['maxValue']}
            ]]>
        </value>
    </property>
    <property name="rowMapper">
        <bean class="com.spring.mybatch.EmpTxnRowMapper" />
    </property>
    <property name="verifyCursorPosition" value="false" />
</bean>

<bean id="databaseWriter" class="org.springframework.batch.item.database.JdbcBatchItemWriter">
    <property name="dataSource" ref="dataSource" />
    <property name="sql">
        <value><![CDATA[update emp_txn set txn_status=:txnStatus where emp_txn_id=:empTxnId]]></value>
    </property>
    <property name="itemSqlParameterSourceProvider">
        <bean class="org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider" />
    </property>
</bean>

<bean id="itemProcessor" class="org.springframework.batch.item.support.CompositeItemProcessor" scope="step">
    <property name="delegates">
        <list>
            <ref bean="processor1" />
            <ref bean="processor2" />
        </list>
    </property>
</bean>

我的自定义范围分区程序将根据emp_txn记录的主键拆分它。

假设emp(主键 - emp_id)可以处理多个emp_txn(主键 - emp_txn_id)。使用我当前的设置,它可以在ItemProcessor(处理器1或处理器2)中,2个线程可以处理同一雇员的emp_txn(即,对于相同的emp_id)。

不幸的是,处理(在处理器2中)emp_txn的后端逻辑不能并行处理相同emp的事务。春季批次有没有办法控制这种处理的顺序?

1 个答案:

答案 0 :(得分:0)

根据您描述的用例,我认为您的分区是错误的。我用emp而不是emp-txn进行分区。这会将实体分组,你可以在那里订购。它还可以防止因为首先根据哪个线程获取它而无法处理emp-txns的风险。

要回答你的直接问题,不。没有办法在单独的线程中订购通过处理器的项目。一旦打破分区步骤,每个分区都可以独立工作。