Spring Batch - 如何使用单个大型XML实现多线程/分区 - StaxEventItemReader

时间:2015-03-10 08:15:00

标签: multithreading spring spring-batch partitioning stax

我正在使用Spring Batch 3.2将数据从XML批量迁移到数据库。

我的XML包含大约140K用户,我想将其转储到数据库中。

我不想在一个帖子中继续进行。

我尝试使用TaskExecutor但由于以下错误而无法成功。

at java.lang.Thread.run(Thread.java:724)
Caused by: com.ctc.wstx.exc.WstxParsingException: Unexpected close tag </consumerName>; expected </first>.
 at [row,col {unknown-source}]: [4814,26]
    at com.ctc.wstx.sr.StreamScanner.constructWfcException(StreamScanner.java:606)
    at com.ctc.wstx.sr.StreamScanner.throwParseError(StreamScanner.java:479)
    at com.ctc.wstx.sr.StreamScanner.throwParseError(StreamScanner.java:464)
    at com.ctc.wstx.sr.BasicStreamReader.reportWrongEndElem(BasicStreamReader.java:3283)
    at com.ctc.wstx.sr.BasicStreamReader.readEndElem(BasicStreamReader.java:3210)
    at com.ctc.wstx.sr.BasicStreamReader.nextFromTree(BasicStreamReader.java:2829)
    at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1072)
    at org.codehaus.stax2.ri.Stax2EventReaderImpl.peek(Stax2EventReaderImpl.java:367)
    at org.springframework.batch.item.xml.stax.DefaultFragmentEventReader.nextEvent(DefaultFragmentEventReader.java:114)
    at org.springframework.batch.item.xml.stax.DefaultFragmentEventReader.markFragmentProcessed(DefaultFragmentEventReader.java:184)

其中consumerNamefirst是XML节点。

我知道StaxEventItemReader不是线程安全且多线程正在使用XML,并且由于这个问题,将片段标记为已处理存在一些问题,我无法获得唯一记录以及完整片段处理。

任何人都可以建议我如何在我的案例中使用多线程/分区。

我想要什么

  • 通过使用多线程,我如何确保每个线程获得独特的卡盘,即(线程1 - fragement 1-100,线程2 - fragement 101-200 ....等等)
  • 每个线程处理唯一的chuck并转储到DB中。

我的配置

<batch:job id="sampleJob">
        <batch:step id="multiThreadStep" allow-start-if-complete="true">
            <batch:tasklet transaction-manager="transactionManager" task-executor="taskExecutor"  throttle-limit="10">
                <batch:chunk reader="xmlItemReader" writer="itemWriter" 
                    processor="itemProcessor" commit-interval="10" skip-limit="1500000">
                    <batch:skippable-exception-classes>
                        <batch:include class="java.lang.Exception" />
                    </batch:skippable-exception-classes>
                </batch:chunk>
            </batch:tasklet>
        </batch:step>
    </batch:job>

    <!-- <bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor">
        <property name="concurrencyLimit" value="10"/>
    </bean>  -->

    <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <property name="corePoolSize" value="10" />
        <property name="maxPoolSize" value="10" />
        <property name="allowCoreThreadTimeOut" value="true" />
    </bean>

<bean id="xmlItemReader" class="org.springframework.batch.item.xml.StaxEventItemReader">
    <property name="fragmentRootElementName" value="userItem" />
    <property name="unmarshaller" ref="userDetailUnmarshaller" />
    <property name="saveState" value="false" />
</bean>

示例XML

<userItems>
     <userItem>
     <...>
     <...>
     </userItem>     
     <userItem>
     <...>
     <...>
     </userItem>
     ...
     ...
</userItems>

0 个答案:

没有答案