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 根据哪个线程首先到达它而被乱序处理的风险。
回答你的直接问题,没有。无法在单独的线程中对通过处理器的项目进行排序。一旦将步骤分解为分区,每个分区独立工作。
这是我的 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 根据哪个线程首先到达它而被乱序处理的风险。
回答你的直接问题,没有。无法在单独的线程中对通过处理器的项目进行排序。一旦将步骤分解为分区,每个分区独立工作。