Spring Batch: java.io.IOException: flusso chiuso eccezione durante la combinazione di MultiResourceItemWriter e FlatFileItemWriter

StackOverflow https://stackoverflow.com/questions/1804042

  •  05-07-2019
  •  | 
  •  

Domanda

Ho un processo Spring Batch che prende un set di righe nel database e crea un numero di file flat da quelle righe, 10 righe per file. Per fare ciò, ho creato un processo Spring Batch, simile al seguente:

<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" />

L'esempio sopra riportato legge da un file flat e restituisce un file flat (per mostrare il problema). Nota commit-intervallo = 2 nel blocco e itemCountLimitPerResource = 2 in MultiResourceItemWriter.

HeaderFooterCallback effettua le seguenti operazioni:

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

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

Devo essere in grado di specificare esattamente il numero di righe che compaiono nel file.

Per il seguente file di input:

foo1
foo2
foo3

Mi aspetto due file in uscita,


out.1:

file header
foo1
foo2
file footer

out.2:

file header
foo3
file footer

Quando corro con commit-intervallo = 2, ottengo un'eccezione:

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).

Penso che questo sia un bug. Stranamente, i file sono i seguenti:

out.1:

file header
foo1
foo2

out.2:

file footer

Se ho due righe nel file di input, tutto funziona correttamente, ma più di due non funzionano. Se cambio l'intervallo di commit su 200, ottengo tre righe in un file, che non è il comportamento desiderato.

Se qualcuno potesse dirmi se sto facendo qualcosa di sbagliato, o se non come aggirare il problema, sarei molto grato.

È stato utile?

Soluzione

In realtà, questo è un bug. Vedi http://jira.springframework.org/browse/BATCH-1452 .

La soluzione alternativa, secondo Dave Syer , è:

  

IOException è brutta. Un parziale   soluzione alternativa è utilizzare il nuovo   proprietà transazionale a   FlatFileItemWriter, impostandolo su   falso (BATCH-1449). Ma poi perdi   Restartability (quindi se non è un   problema sei pronto per andare). Ci proverò   e risolverlo correttamente per 2.1.

     

Un'altra soluzione alternativa è pubblicare il processo   i file in un passaggio separato (e non   utilizzare i callback di intestazione / piè di pagina).

     

Il problema del conteggio (più di 2 articoli   per file) è davvero separato: il   scrittore multi-risorsa non è mai stato   progettato per garantire la precisione   numero di elementi per file, solo a   traboccare se il limite viene violato.   È possibile aprire un JIRA per un miglioramento   se vuoi, una soluzione alternativa è da usare   commit-interval = " 2 " nel tuo esempio   (o più in generale un fattore del   dimensione del file desiderata).

Altri suggerimenti

Considera, stai provando a leggere i dati da db e a scriverli in un file. In questo scenario, quando si scrivono i dati in un file, è necessario un oggetto da utilizzare in " HeaderFooterCallback " file. come si fa?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top