From df1e4a460572a82dc4c08053ed81fb8f54eb719d Mon Sep 17 00:00:00 2001 From: robokaso Date: Wed, 19 Nov 2008 13:01:40 +0000 Subject: [PATCH] IN PROGRESS - BATCH-929: Deferrable Constraints cause unrecoverable errors count non-fatal commit failure as rollback --- .../batch/core/step/tasklet/TaskletStep.java | 20 +++++++++++++++---- .../step/item/TaskletStepExceptionTests.java | 3 ++- .../integration/JobRepositorySupport.java | 9 +++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/TaskletStep.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/TaskletStep.java index 1515c27cd..d471b5207 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/TaskletStep.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/tasklet/TaskletStep.java @@ -297,9 +297,7 @@ public class TaskletStep extends AbstractStep { } catch (Exception e) { if (nonFatalCommitExceptions.classify(e)) { - stepExecution.setExecutionContext(getJobRepository().getExecutionContext(stepExecution)); - JobExecution jobExecution = stepExecution.getJobExecution(); - jobExecution.setExecutionContext(getJobRepository().getExecutionContext(jobExecution)); + rollbackExecutionContext(stepExecution); throw new CommitException("non-fatal commit failure", e); } else { @@ -326,10 +324,15 @@ public class TaskletStep extends AbstractStep { throw e; } catch (Exception e) { - // if commit failed, calling rollback on tx manager would cause exception + // if commit failed, calling rollback on tx manager would + // cause exception if (!(e instanceof CommitException)) { processRollback(stepExecution, fatalException, transaction); } + else { + // assume the failed commit caused rollback + stepExecution.rollback(); + } throw e; } finally { @@ -348,6 +351,15 @@ public class TaskletStep extends AbstractStep { return result; } + /** + * Load the saved value of ExecutionContext from repository. + */ + private void rollbackExecutionContext(StepExecution stepExecution) { + stepExecution.setExecutionContext(getJobRepository().getExecutionContext(stepExecution)); + JobExecution jobExecution = stepExecution.getJobExecution(); + jobExecution.setExecutionContext(getJobRepository().getExecutionContext(jobExecution)); + } + }); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/TaskletStepExceptionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/TaskletStepExceptionTests.java index 91bdabc62..509c7b597 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/TaskletStepExceptionTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/TaskletStepExceptionTests.java @@ -199,7 +199,7 @@ public class TaskletStepExceptionTests { * status and execution context should be rolled back. */ @Test - public void testSkippableCommitError() throws Exception { + public void testNonFatalCommitError() throws Exception { class TestItemStream extends ItemStreamSupport { private boolean called = false; @@ -240,6 +240,7 @@ public class TaskletStepExceptionTests { assertEquals("step won't refuse to restart", FAILED, stepExecution.getStatus()); assertTrue("execution context modified", stream.called); assertTrue("execution context rolled back", stepExecution.getExecutionContext().isEmpty()); + assertEquals("failed commit counted as rollback", 1, stepExecution.getRollbackCount()); } @Test diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/JobRepositorySupport.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/JobRepositorySupport.java index 70d052345..622391d4d 100644 --- a/spring-batch-integration/src/test/java/org/springframework/batch/integration/JobRepositorySupport.java +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/JobRepositorySupport.java @@ -23,6 +23,7 @@ import org.springframework.batch.core.repository.JobExecutionAlreadyRunningExcep import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.repository.JobRestartException; +import org.springframework.batch.item.ExecutionContext; /** * @author Dave Syer @@ -87,4 +88,12 @@ public class JobRepositorySupport implements JobRepository { return null; } + public ExecutionContext getExecutionContext(StepExecution stepExecution) { + return null; + } + + public ExecutionContext getExecutionContext(JobExecution jobExecution) { + return null; + } + }