哪个线程安全的JobRepository用于多线程步骤?

时间:2014-07-08 10:35:04

标签: multithreading spring spring-batch

在使用分区运行spring批处理作业时,每个从属线程都失败并出现以下错误:

[SimpleAsyncTaskExecutor-2] AbstractStep.execute(250) | Encountered an error saving batch meta data. This job is now in an unknown state and should not be restarted. org.springframework.dao.OptimisticLockingFailureException: Attempt to update step execution id=4623 with wrong version (1), where current version is 2 at org.springframework.batch.core.repository.dao.JdbcStepExecutionDao.updateStepExecution(JdbcStepExecutionDao.java:185) at org.springframework.batch.core.repository.support.SimpleJobRepository.update(SimpleJobRepository.java:171)

正在使用的Job Repository是JobRepositoryFactoryBean。 Spring批量版本是2.1.8。 在BATCH_STEP_EXECUTION表中,对于所有步骤,版本为2,即使是第一次运行这些步骤。

作业配置如下:

<job id="partitionJob" xmlns="http://www.springframework.org/schema/batch" parent="simpleJob">
    <step id="masterStep" xmlns="http://www.springframework.org/schema/batch" parent="skipLimitStep">
        <partition step="slave" partitioner="BulkPartitioner" xmlns="http://www.springframework.org/schema/batch">
        <handler grid-size="10" task-executor="asyncTaskExecutor" xmlns="http://www.springframework.org/schema/batch" />
        </partition>
    </step>
</job>

<step id="slave" xmlns="http://www.springframework.org/schema/batch" parent="skipLimitStep">
    <tasklet>
        <chunk reader="partitionPagingItemReader" writer="partitionItemWriter"   commit-interval="1"  processor="partitionitemProcessor" skip-limit="1000">
        </chunk>
        <transaction-attributes propagation="REQUIRES_NEW" />
    </tasklet>
</step>

<bean id="BulkPartitioner" class="foo.bar.BulkPartitioner" scope="step"  >
    <property name="model" value="#{jobParameters['abc']}"/>
</bean>

<bean id="partitionPagingItemReader" class="org.springframework.batch.item.database.JdbcPagingItemReader" scope="step" >
    <property name="dataSource" ref="dataSource" />
    <!--  <property name="fetchSize" value="#{jobParameters['fetch.size']}"></property>  -->
    <property name="fetchSize" value="1000"></property>
    <property name="queryProvider">
        <bean class="org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="selectClause" value="select a, b, c" />
            <property name="fromClause" value="from d" />
            <property name="whereClause" value="where e= :f" /> 
            <property name="sortKey" value="e" />
        </bean>
    </property>
    <!-- Inject via the ExecutionContext in rangePartitioner -->
    <property name="parameterValues">
        <map>
            <entry key="f" value="#{stepExecutionContext[f]}" />  
        </map>
    </property>
    <property name="pageSize" value="1" />
    <property name="rowMapper">
        <bean class="foo.bar.mapper" />
    </property>
</bean>

 <bean id="simpleJob" 
      class="org.springframework.batch.core.job.SimpleJob" abstract="true">
     <property name="jobRepository" ref="jobRepository"/>
    <property name="restartable" value="true"/>
</bean>

 <bean id="jobRepository" 
      class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="databaseType" value="oracle"/>
    <property name="transactionManager" ref="transactionManager"/>
    <property name="isolationLevelForCreate" value="ISOLATION_DEFAULT"/>
    <property name="validateTransactionState" value="false"/>
</bean>

更新:仅在失败的步骤中发生这种情况。成功完成步骤已正确更新。

可能是什么原因? TIA。

1 个答案:

答案 0 :(得分:1)

如果这是其他人的问题,这是我找到的解决方案:

<property name="saveState" value="false" />
用于并发作业/步骤的读取器/写入器中的

。正如日志中提到的那样,“此作业现在处于未知状态,不应重新启动”,因此您应该考虑:

<property name="restartable" value="false"/>

来源:

http://docs.spring.io/spring-batch/reference/html/scalability.html http://docs.spring.io/spring-batch/reference/html/readersAndWriters.html#process-indicator