代码之家  ›  专栏  ›  技术社区  ›  Matthew Farwell

Spring批处理:java.io.ioException:在组合multResourceItemWriter和flatFileItemWriter时流关闭异常

  •  1
  • Matthew Farwell  · 技术社区  · 16 年前

    我有一个Spring批处理过程,它在数据库中获取一组行,并从这些行创建许多平面文件,每个文件10行。为此,我创建了一个Spring批处理过程,类似于:

    <batch:job id="springTest" job-repository="jobRepository" restartable="true">
        <batch:step id="test">
            <batch:tasklet>
                <batch:chunk reader="itemReader" writer="multipleItemWriter" commit-interval="2" />
            </batch:tasklet>
        </batch:step>
    </batch:job>
    
    <bean id="itemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
        <property name="resource" value="file:/temp/temp-input.txt" />
        <property name="lineMapper">
            <bean class="org.springframework.batch.item.file.mapping.PassThroughLineMapper" />
        </property>
    </bean>
    
    <bean id="multipleItemWriter" class="org.springframework.batch.item.file.MultiResourceItemWriter">
        <property name="resource" value="file:/temp/temp-out" />
        <property name="itemCountLimitPerResource" value="2" />
        <property name="delegate">
            <bean id="itemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter">
                <property name="lineAggregator">
                  <bean class="org.springframework.batch.item.file.transform.PassThroughLineAggregator" />
                </property>
                <property name="encoding" value="utf-8" />
                <property name="headerCallback" ref="headerFooter" />
                <property name="footerCallback" ref="headerFooter" />
            </bean>
       </property>
    </bean>
    
    <bean id="headerFooter" class="uk.co.farwell.spring.HeaderFooterCallback" />
    

    上面的示例从平面文件读取并输出到平面文件(以显示问题)。注意块中的提交间隔=2,multi-resourceitemwriter中的itemcountlimitperresource=2。

    HeaderFooterCallback执行以下操作:

    public void writeHeader(Writer writer) throws IOException {
        writer.write("file header\n");
    }
    
    public void writeFooter(Writer writer) throws IOException {
        writer.write("file footer\n");
    }
    

    我需要能够准确地指定文件中出现的行数。

    对于以下输入文件:

    foo1
    foo2
    foo3
    

    我希望输出两个文件,


    输出。1:

    file header
    foo1
    foo2
    file footer
    

    输出。2:

    file header
    foo3
    file footer
    

    当我以commit interval=2运行时,我得到一个异常:

    2009-11-26 15:32:46,734 ERROR .support.TransactionSynchronizationUtils - TransactionSynchronization.afterCompletion threw exception
    org.springframework.batch.support.transaction.FlushFailedException: Could not write to output buffer
        at org.springframework.batch.support.transaction.TransactionAwareBufferedWriter$1.afterCompletion(TransactionAwareBufferedWriter.java:71)
        at org.springframework.transaction.support.TransactionSynchronizationUtils.invokeAfterCompletion(TransactionSynchronizationUtils.java:157)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.invokeAfterCompletion(AbstractPlatformTransactionManager.java:974)
        .
        .
        .
    Caused by: java.io.IOException: Stream closed
        at sun.nio.cs.StreamEncoder.ensureOpen(Unknown Source)
        at sun.nio.cs.StreamEncoder.write(Unknown Source)
        at sun.nio.cs.StreamEncoder.write(Unknown Source)
        at java.io.Writer.write(Unknown Source)
        at org.springframework.batch.support.transaction.TransactionAwareBufferedWriter$1.afterCompletion(TransactionAwareBufferedWriter.java:67).
    

    我觉得这是个虫子。最后,文件如下:

    输出。1:

    file header
    foo1
    foo2
    

    输出。2:

    file footer
    

    如果输入文件中有两行,则一切都正常工作,但超过两行不工作。如果我将提交间隔更改为200,那么在一个文件中会得到三行,这不是需要的行为。

    如果有人能告诉我我是不是做错了什么事,或者不是怎么解决这个问题,我会非常感激的。

    2 回复  |  直到 14 年前
        1
  •  3
  •   Matthew Farwell    16 年前

    实际上,这是一个错误。见 http://jira.springframework.org/browse/BATCH-1452 .

    根据 Dave Syer 是:

    IOexception很讨厌。部分 解决方法是使用新的 中的事务属性 FlatfileItemWriter,将其设置为 假(批次1449)。但是你输了 可重启性(如果不是 问题是你可以走了)。我会尝试 并为2.1正确固定。

    另一个解决方法是发布流程 单独步骤中的文件(而不是 使用页眉/页脚回调)。

    盘点问题(2项以上 每个文件)都是独立的 多资源编写器从未 旨在确保 每个文件的项目数,仅限于 如果超过限制,溢出。 您可以打开一个jira进行增强 如果你愿意,一个解决方法就是 在您的示例中,commit interval=“2” (或者更一般地说是 所需文件大小)。

        2
  •  1
  •   Sriram    14 年前

    考虑一下,您正在尝试从数据库读取数据并将其写入文件。在这种情况下,将数据写入文件时,需要在“headerfootercallback”文件中使用一个对象。你是怎么做到的?