Spring Batch:始终使用MultiResourceItemReader查找文件

时间:2012-03-26 13:12:18

标签: input xml-parsing spring-batch

我是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 不能正常工作,特别是在输入错误中。

我希望这会有所帮助。最好的问候

2 个答案:

答案 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不能按预期工作,特别是在输入错误中。

我希望这会有所帮助。最好的问候