我使用Spring批处理分区技术来处理块中的记录。我有一个控制器来启动作业和分区程序,以便在40个线程之间平均分配记录。由于我们已经实现了分页并在我们的项目中使用JPA,这就是我们使用JPAPagingItemReader的原因。 writer类正在实现ItemWriter。有人可以帮我解决这个问题吗
org.springframework.batch.core.step.FatalStepExecutionException: JobRepository failure forcing rollback
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:459)
at org.springframework.batch.costrong textre.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:271)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:257)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:198)
at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:139)
at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:136)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:926)
at java.util.HashMap$KeyIterator.next(HashMap.java:960)
at com.thoughtworks.xstream.converters.collections.CollectionConverter.marshal(CollectionConverter.java:73)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:88)
at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeItem(AbstractCollectionConverter.java"
作业report.xml将
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch-2.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.2.xsd">
<job id="testChunkJob" xmlns="http://www.springframework.org/schema/batch">
<step id="testMasterStep">
<partition step="testSlaveStep" partitioner="testPartitioner">
<handler grid-size="40" task-executor="multiThreadedTaskExecutor" />
</partition>
</step>
<batch:listeners>
<batch:listener ref="baseJobListener" />
</batch:listeners>
</job>
<step id="testSlaveStep" xmlns="http://www.springframework.org/schema/batch">
<tasklet>
<chunk reader="testChunkReader" processor="testChunkProcessor" writer="testChunkWriter" commit-interval="50" />
<batch:listeners>
<listener ref="baseItemListener" />
</batch:listeners>
</tasklet>
<listeners>
<listener ref="baseStepListener" />
</listeners>
</step>
<bean id="multiThreadedTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="40" />
<property name="maxPoolSize" value="40" />
<property name="allowCoreThreadTimeOut" value="true" />
</bean>
<bean id="baseJobListener" class="com.test.batch.listener.BaseJobListener" />
<bean id="baseItemListener" class="com.test.batch.listener.BaseItemListener" />
<bean id="baseStepListener" class="com.test.batch.listener.BaseStepListener" />
<bean id="testPartitioner" class="com.test.batch.partitioner.TestPartitioner"/>
<bean id="testChunkReader"
class="com.test.batch.reader.TestChunkReader" scope="step">
<property name="minValue" value="#{stepExecutionContext[minValue]}" />
<property name="maxValue" value="#{stepExecutionContext[maxValue]}" />
<property name="gtfContext" value="#{stepExecutionContext[gtfContext]}" />
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="pageSize" value="40" />
</bean>
<bean id="testChunkProcessor" class="com.test.batch.processing.TestChunkProcessor" scope="step"/>
<bean id="testChunkWriter" class="com.test.batch.writer.TestChunkWriter" scope="step"/>
</beans>