【发布时间】:2012-03-26 13:12:18
【问题描述】:
我是 Spring Batch 的新手。我继承了一个用 Spring Batch 实现的批处理。 这很好用,除了我将尝试描述的一件事。
我启动 parseJob,当它读取 XML 以在 bean parsingStepReader 中处理时, read() 方法一直在调用。
目录*path_to_xml*只包含一个XML,调用read()返回解析后的XML,处理OK。然后,再次调用read()方法,返回一个null对象,再次调用,返回null……以此类推。
调试时,MultiResourceItemReader read 方法尝试读取,不读取任何内容(所有资源都已读取),增加 currentResources 并返回 null。
我读过一些关于当阅读器返回空对象时作业停止的内容,但是 read 方法返回 null 并一次又一次地读取...... 我把restartable改成false了,还是不行。
作业在 Linux 中以批处理模式启动,使用 org.springframework.batch.core.launch.support.CommandLineJobRunner 因为这个问题,启动job的.sh没有完成,资源很忙。
我怎样才能避免这种情况,或者在资源 (XML) 输入目录已经被处理时停止工作? 任何帮助将不胜感激。最好的问候。
附上 Beans 文件和 Java 类片段
<batch:job id="parseJob" restartable="true" incrementer="jobParametersIncrementer">
<batch:flow parent="parseFlow"/>
<batch:flow .../>
<batch:flow .../>
</batch:job>
<batch:flow id="parseFlow">
<batch:step id="parsingStep">
<batch:tasklet start-limit="100" allow-start-if-complete="true" transaction-manager="..." task-executor="taskExecutor" throttle-limit="$...">
<batch:chunk reader="parsingStepReader" writer="..." processor="..." commit-interval="..." skip-limit="10000000">
<batch:skippable-exception-classes>
<batch:include class="java.lang.Exception" />
</batch:skippable-exception-classes>
</batch:chunk>
<batch:listeners>
<batch:listener ref="iwListener" />
<batch:listener ref="mySkipListener" />
<batch:listener ref="myStep1Listener" />
</batch:listeners>
<batch:no-rollback-exception-classes>
<batch:include class="java.lang.Exception" />
</batch:no-rollback-exception-classes>
</batch:tasklet>
</batch:step>
</batch:flow>
<!-- -->
<bean id="bpfReader" class="org.springframework.batch.item.xml.StaxEventItemReader" scope="prototype">
<property name="fragmentRootElementName" value="..." />
<property name="unmarshaller" ref="..." />
<property name="strict" value="false" />
</bean>
<bean id="multiresourceItemReader" class="...SyncMultiResourceItemReader" abstract="true">
<property name="strict" value="false" />
<property name="delegate" ref="bpfReader" />
</bean>
<bean id="parsingStepReader" parent="multiresourceItemReader" scope="step">
<property name="resources" value="<path_to_xml>" />
</bean>
而阅读器类是:
public class SyncMultiResourceItemReader<T> extends MultiResourceItemReader<T> {
. . .
@Override
public T read() throws Exception, UnexpectedInputException, ParseException {
synchronized (this) {
return super.read();
}
}
. . .
}
更新:@vsingh 建议的解决方案完美运行。一旦选择了输入元素,就必须将其从输入中删除。我不知道为什么,但是类 org.springframework.batch.item.file.MultiResourceItemReader 没有按我的预期工作,尤其是在输入错误时。
我希望这会有所帮助。最好的问候
【问题讨论】:
-
您能否更准确地解决这个问题:
MultiResourceItemReader#read()返回null,因为输入资源被锁定?还是 Spring Batch 继续调用read()方法,尽管它刚刚返回了null? -
@dma_k,当您阐明问题时,错误的问题在于您的第二种方式,因此
read()返回 null,并被一次又一次地调用。我认为解决方案类似于 [this] (stackoverflow.com/questions/7781012/…),但我还不清楚。谢谢@dma_k
标签: input xml-parsing spring-batch