RESOLVED - BATCH-847: FaultTolerantChunkOrientedTasklet loses chunks when non-skippable exceptions thrown in read phase

used fatal NonSkippableReadException instead of reusing SkipLimitExceededException
This commit is contained in:
robokaso
2008-09-30 11:32:41 +00:00
parent 03a3f2d219
commit 78ed0075ea
4 changed files with 22 additions and 4 deletions

View File

@@ -10,6 +10,7 @@ import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.listener.CompositeSkipListener;
import org.springframework.batch.core.step.skip.ItemSkipPolicy;
import org.springframework.batch.core.step.skip.LimitCheckingItemSkipPolicy;
import org.springframework.batch.core.step.skip.NonSkippableReadException;
import org.springframework.batch.core.step.skip.SkipLimitExceededException;
import org.springframework.batch.item.ItemKeyGenerator;
import org.springframework.batch.item.ItemReader;
@@ -205,6 +206,7 @@ public class SkipLimitStepFactoryBean extends SimpleStepFactoryBean {
if (retryLimit > 0 || skipLimit > 0 || retryPolicy != null) {
addFatalExceptionIfMissing(SkipLimitExceededException.class);
addFatalExceptionIfMissing(NonSkippableReadException.class);
addFatalExceptionIfMissing(RetryException.class);
if (retryPolicy == null) {
@@ -385,8 +387,7 @@ public class SkipLimitStepFactoryBean extends SimpleStepFactoryBean {
onSkipInRead(e);
logger.debug("Skipping failed input", e);
} else {
// re-throw the same way as exceeding skip limit (fatal)
throw new SkipLimitExceededException(0, e);
throw new NonSkippableReadException("Non-skippable exception during read", e);
}
} catch (SkipLimitExceededException ex) {
// we are headed for a abnormal ending so bake in the

View File

@@ -0,0 +1,15 @@
package org.springframework.batch.core.step.skip;
import org.springframework.core.NestedRuntimeException;
public class NonSkippableReadException extends NestedRuntimeException {
public NonSkippableReadException(String msg, Throwable cause) {
super(msg, cause);
}
public NonSkippableReadException(String msg) {
super(msg);
}
}

View File

@@ -18,6 +18,7 @@ import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.step.AbstractStep;
import org.springframework.batch.core.step.JobRepositorySupport;
import org.springframework.batch.core.step.skip.NonSkippableReadException;
import org.springframework.batch.core.step.skip.SkipLimitExceededException;
import org.springframework.batch.item.ClearFailedException;
import org.springframework.batch.item.FlushFailedException;
@@ -118,7 +119,7 @@ public class SkipLimitStepFactoryBeanTests extends TestCase {
step.execute(stepExecution);
fail();
}
catch (SkipLimitExceededException e) {
catch (NonSkippableReadException e) {
assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
assertEquals(1, stepExecution.getItemCount().intValue());
}

View File

@@ -37,6 +37,7 @@ import org.springframework.batch.core.repository.dao.MapJobInstanceDao;
import org.springframework.batch.core.repository.dao.MapStepExecutionDao;
import org.springframework.batch.core.repository.support.SimpleJobRepository;
import org.springframework.batch.core.step.AbstractStep;
import org.springframework.batch.core.step.skip.NonSkippableReadException;
import org.springframework.batch.core.step.skip.SkipLimitExceededException;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
@@ -143,7 +144,7 @@ public class StatefulRetryStepFactoryBeanTests extends TestCase {
step.execute(stepExecution);
fail();
}
catch (SkipLimitExceededException expected) {
catch (NonSkippableReadException expected) {
assertEquals(0, stepExecution.getSkipCount());
// b is processed twice, plus a, plus c, plus the null at end