diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/AbstractStep.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/AbstractStep.java index 5a1de1ce3..5df121a7b 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/AbstractStep.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/AbstractStep.java @@ -326,7 +326,7 @@ public abstract class AbstractStep implements Step, InitializingBean, BeanNameAw * {@link BatchStatus#UNKNOWN} as step's status. */ protected static class FatalException extends RuntimeException { - public FatalException(String string, Exception e) { + public FatalException(String string, Throwable e) { super(string, e); } } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/ItemOrientedStep.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/ItemOrientedStep.java index 0f5e7591c..ee1d25fa3 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/ItemOrientedStep.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/ItemOrientedStep.java @@ -265,18 +265,23 @@ public class ItemOrientedStep extends AbstractStep { throw new FatalException("Fatal error detected during save of step execution context", e); } + itemHandler.mark(); + try { - itemHandler.mark(); transactionManager.commit(transaction); } catch (Exception e) { - fatalException.setException(e); - stepExecution.setStatus(BatchStatus.UNKNOWN); logger.error("Fatal error detected during commit."); - throw new FatalException("Fatal error detected during commit", e); + throw new CommitException("Fatal error detected during commit - " + + "the execution is in undefined state and restart will not be possible", e); } } + catch (CommitException e) { + // trying to rollback after failed commit would just be + // asking for more trouble - die ASAP + throw e; + } catch (Error e) { processRollback(stepExecution, contribution, fatalException, transaction); throw e; @@ -382,6 +387,15 @@ public class ItemOrientedStep extends AbstractStep { } + /** + * Encapsulates exception thrown while committing transaction. + */ + private static class CommitException extends FatalException { + public CommitException(String msg, Throwable cause) { + super(msg, cause); + } + } + protected void close(ExecutionContext ctx) throws Exception { stream.close(ctx); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ItemOrientedStepTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ItemOrientedStepTests.java index e48e7dc67..667ff3566 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ItemOrientedStepTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ItemOrientedStepTests.java @@ -654,9 +654,9 @@ public class ItemOrientedStepTests extends TestCase { catch (RuntimeException ex) { assertEquals(BatchStatus.UNKNOWN, stepExecution.getStatus()); String msg = stepExecution.getExitStatus().getExitDescription(); - assertTrue(msg.contains("Fatal error detected during commit")); + assertTrue(msg.contains("Fatal error detected during commit - the execution is in undefined state and restart will not be possible")); msg = ex.getMessage(); - assertTrue(msg.contains("Fatal error detected during commit")); + assertTrue(msg.contains("Fatal error detected during commit - the execution is in undefined state and restart will not be possible")); // The original rollback was caused by this one: assertEquals("Bar", ex.getCause().getMessage()); }