2012-02-07 9 views
5

Tengo un programa de lotes de muelles.comportamiento extraño en el lote de primavera sobre la implementación de la política de omisión

El límite de salto se establece en 5 y el tamaño del fragmento es 1000.

Tengo un trabajo con dos pasos de la siguiente manera:

<step id="myFileGenerator" next="myReportGenerator"> 
     <tasklet transaction-manager="jobRepository-transactionManager"> 
      <chunk reader="myItemReader" processor="myItemProcessor" writer="myItemWriter" commit-interval="1000" skip-policy="skipPolicy"/> 
     </tasklet> 
     <listeners> 
      <listener ref="mySkipListener"/> 
     </listeners> 
    </step> 

    <step id="myReportGenerator"> 
     <tasklet ref="myReportTasklet" transaction-manager="jobRepository-transactionManager"/> 
    </step> 

La política de salto es la siguiente:

<beans:bean id="skipPolicy" class="com.myPackage.util.Skip_Policy"> 
    <beans:property name="skipLimit" value="5"/> 
</beans:bean> 
clase

El SkipPolicy es la siguiente:

public class Skip_Policy implements SkipPolicy { 

private int skipLimit; 

public void setSkipLimit(final int skipLimit) { 
    this.skipLimit = skipLimit; 
} 

public boolean shouldSkip(final Throwable t, final int skipCount) throws SkipLimitExceededException { 

    if (skipCount < this.skipLimit) { 
     return true; 
    } 
    return false; 
} 
} 

Por lo tanto, para cualquier error que ocurra antes de que se alcance el límite de omisión, la política de omisión ignorará el error (devuelve verdadero). El trabajo fallará por cualquier error después de que se alcance el límite de omisión.

La clase mySkipListener es la siguiente:

public class mySkipListener implements SkipListener<MyItem, MyItem> { 

public void onSkipInProcess(final MyItem item, final Throwable t) { 
    // TODO Auto-generated method stub 
    System.out.println("Skipped details during PROCESS is: " + t.getMessage()); 
} 

public void onSkipInRead(final Throwable t) { 

    System.out.println("Skipped details during READ is: " + t.getMessage()); 
} 

public void onSkipInWrite(final MyItem item, final Throwable t) { 
    // TODO Auto-generated method stub 
    System.out.println("Skipped details during WRITE is: " + t.getMessage()); 
} 
} 

Ahora en myItemProcessor que tienen debajo de bloque de código:

if (item.getTheNumber().charAt(4) == '-') { 
     item.setProductNumber(item.getTheNumber().substring(0, 3)); 
    } else { 
     item.setProductNumber("55"); 
    } 

Para algunos de los artículos Thenumber campo es nulo y así por encima de código de bloque tiros " StringIndexOutofBounds "excepción.

Pero estoy viendo un comportamiento extraño que no entiendo por qué está sucediendo.

En total hay 6 elementos que tienen un error, es decir, el campo Número es nulo.

Si el límite de omisión es mayor que el número de errores (es decir,> 6), se invocan los sys outs en la clase de escucha de omisión y se informan los errores omitidos.

Sin embargo, si el límite de salto es menor (por ejemplo 5 como en mi ejemplo), las salidas sys en clase de escucha de salto no están siendo llamados en absoluto y estoy recibiendo directamente al vertedero excepción abajo en la consola:

org.springframework.batch.retry.RetryException: Non-skippable exception in recoverer while processing; nested exception is java.lang.StringIndexOutOfBoundsException 
at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor$2.recover(FaultTolerantChunkProcessor.java:282) 
at org.springframework.batch.retry.support.RetryTemplate.handleRetryExhausted(RetryTemplate.java:416) 
at org.springframework.batch.retry.support.RetryTemplate.doExecute(RetryTemplate.java:285) 
at org.springframework.batch.retry.support.RetryTemplate.execute(RetryTemplate.java:187) 

¿Cuál es la razón detrás de este comportamiento? ¿Qué debo hacer para resolver esto?

¡Gracias por leer!

Respuesta

2

SkipListener solo se usa al final del fragmento, si la tarea que lo contiene termina normalmente. Cuando tiene más errores que el límite de omisión, eso se informa, a través de la excepción que ve, y la tarea se cancela.

Si el número de errores es inferior al límite de omisión, la tarea finaliza normalmente y SkipListener se invoca una vez por cada línea omitida - Spring Batch crea una lista interna a medida que avanza, pero solo informa al final.

La idea si esto es que si la tarea falla, probablemente la vuelva a intentar, por lo que no es útil saber qué se saltó durante una ejecución incompleta, cada vez que vuelva a intentar obtendrá la misma notificación. Solo si todo lo demás tiene éxito, puedes ver lo que se saltó. Imagine que está registrando los elementos omitidos, no quiere que se registren como salteados una y otra vez.

Como ha visto, la solución más simple es hacer que el límite de saltos sea lo suficientemente grande. De nuevo, la idea es que si tiene que omitir muchos elementos, probablemente haya un problema más serio.

Cuestiones relacionadas