我是批量 生产环境 的新蜜蜂 . 我的要求是从数据库表中获取记录,处理它们(每个记录可以独立处理,因此我正在分区并使用任务执行程序),然后根据处理状态更新同一个表中的状态列 .

我的代码的简化版本如下 .

Item Reader (我的自定义列分区程序将决定下面的最小值和最大值):

<bean name="databaseReader" class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="step">
    <property name="dataSource" ref="dataSource"/>
    <property name="sql">
        <value>
            <![CDATA[
                select id,user_login,user_pass,age from users where id >= #{stepExecutionContext['minValue']} and id <= #{stepExecutionContext['maxValue']}
            ]]>
        </value>
    </property>
    <property name="rowMapper">
        <bean class="com.springapp.batch.UserRowMapper" />
    </property>
    <property name="verifyCursorPosition" value="false"/>
</bean>

Item Processor:

<bean id="itemProcessor" class="com.springapp.batch.UserItemProcessor" scope="step"/>
....

public class UserItemProcessor implements ItemProcessor<Users, Users>
{

    @Override
    public Users process(Users users) throws Exception {
        // do some processing here..
        //update users status
        //users.setStatus(users.getId() + ": Processed by :" + Thread.currentThread().getName() + ": Processed at :" + new GregorianCalendar().getTime().toString());
        //System.out.println("Processing user :" + users + " :" +Thread.currentThread().getName());
        return users;
    }
}

Item Writer:

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

Step configuration:

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

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

<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="3" />
</bean>

由于我已将提交间隔指定为5,因此我的理解是,当分区处理5个项目时,它将使用List of 5 Users对象调用JDBCItemWriter以执行批量JDBC更新 . 但是对于当前设置,我在批量更新期间一次收到1个用户对象 .

我的理解是正确的还是我缺少任何步骤/配置?

注意:我正在使用基于HSQL文件的数据库进行测试 .

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="org.hsqldb.jdbc.JDBCDriver"/>
    <property name="url" value="jdbc:hsqldb:file:C://users.txt"/>
    <property name="username" value="sa"/>
    <property name="password" value=""/>
</bean>