Spring batch ItemProcessor 处理项目的顺序

Spring batch ItemProcessor order of processing the items

这是我的 spring 配置文件。

<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(primary key - emp_id)可以有多个emp_txn(primary key - emp_txn_id)需要处理。使用我当前的设置,在 ItemProcessor(处理器 1 或处理器 2)中,2 个线程可以处理同一员工的 emp_txn(即相同的 emp_id)。

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

对于您描述的用例,我认为您按错误的事物进行了分区。我会按 emp 而不是 emp-txn 进行分区。这会将 emp-txns 分组,您可以在那里订购它们。它还可以防止 emp-txns 根据哪个线程首先到达它而被乱序处理的风险。

回答你的直接问题,没有。无法在单独的线程中对通过处理器的项目进行排序。一旦将步骤分解为分区,每个分区独立工作。