我是Spring Batch的新手。我有继承使用Spring Batch实现的批处理。 这很有效,除了我试图描述的一件事。
我启动 parseJob ,当它读取XML以在bean parsingStepReader 中处理时, read()方法一直在调用。
目录* path_to_xml *只包含一个XML,调用read()并返回解析的XML,处理好了。然后,再次调用read()方法,返回一个null对象,并再次调用,返回null ...依此类推。
调试时,MultiResourceItemReader 读取方法尝试读取,不读取任何内容(所有资源都已被读取),增加currentResources并返回null。
当读者返回一个空对象时,我已经了解了有关作业停止的内容,但 read 方法返回null并一次又一次地读取... 我将restartable更改为false,但不起作用。
该作业在Linux,批处理模式下启动,使用org.springframework.batch.core.launch.support.CommandLineJobRunner 由于此问题,启动作业的.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 不能正常工作,特别是在输入错误中。
我希望这会有所帮助。最好的问候
答案 0 :(得分:2)
read方法将读取数据,在类级别存储并将其传递给write方法。 我将举例说明我们是如何做到的
例如
@Override
public Long read() throws Exception, UnexpectedInputException,
ParseException, NonTransientResourceException {
synchronized (this.myIds) {
if (!this.myIds.isEmpty()) {
return this.myIds.remove(0);
}
return null;
}
}
myIds是班级级别的列表
此列表在步骤方法
之前填充@Override
public void beforeStep(final StepExecution stepExec) {
this.stepExecution = stepExec;
// read the ids from service and set at class level
}
答案 1 :(得分:0)
@vsingh提出的解决方案非常有效。选择输入元素后,必须将其从输入中删除。我不知道为什么,但类org.springframework.batch.item.file.MultiResourceItemReader不能按预期工作,特别是在输入错误中。
我希望这会有所帮助。最好的问候