@Test public void testUnexpectedRollback() throws Exception { taskletStep.setTransactionManager( new ResourcelessTransactionManager() { @Override protected void doCommit(DefaultTransactionStatus status) throws TransactionException { super.doRollback(status); throw new UnexpectedRollbackException("bar"); } }); taskletStep.setTasklet( new Tasklet() { public RepeatStatus execute(StepContribution contribution, ChunkContext attributes) throws Exception { attributes .getStepContext() .getStepExecution() .getExecutionContext() .putString("foo", "bar"); return RepeatStatus.FINISHED; } }); taskletStep.execute(stepExecution); assertEquals(FAILED, stepExecution.getStatus()); Throwable e = stepExecution.getFailureExceptions().get(0); assertEquals("bar", e.getMessage()); assertEquals(0, stepExecution.getCommitCount()); assertEquals(1, stepExecution.getRollbackCount()); // Failed transaction counts as rollback assertEquals(0, stepExecution.getExecutionContext().size()); }
public void afterJob(JobExecution jobExecution) { StringBuilder protocol = new StringBuilder(); protocol.append("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++ \n"); protocol.append("Protocol for " + jobExecution.getJobInstance().getJobName() + " \n"); protocol.append(" Started : " + jobExecution.getStartTime() + "\n"); protocol.append(" Finished : " + jobExecution.getEndTime() + "\n"); protocol.append(" Exit-Code : " + jobExecution.getExitStatus().getExitCode() + "\n"); protocol.append(" Exit-Descr. : " + jobExecution.getExitStatus().getExitDescription() + "\n"); protocol.append(" Status : " + jobExecution.getStatus() + "\n"); protocol.append("+++++++++++++++++++++++++++++++++++++++++++++++++++++++ \n"); protocol.append("Job-Parameter: \n"); JobParameters jp = jobExecution.getJobParameters(); for (Iterator<Entry<String, JobParameter>> iter = jp.getParameters().entrySet().iterator(); iter.hasNext(); ) { Entry<String, JobParameter> entry = iter.next(); protocol.append(" " + entry.getKey() + "=" + entry.getValue() + "\n"); } protocol.append("+++++++++++++++++++++++++++++++++++++++++++++++++++++++ \n"); for (StepExecution stepExecution : jobExecution.getStepExecutions()) { protocol.append("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++ \n"); protocol.append("Step " + stepExecution.getStepName() + " \n"); protocol.append("WriteCount: " + stepExecution.getWriteCount() + "\n"); protocol.append("Commits: " + stepExecution.getCommitCount() + "\n"); protocol.append("SkipCount: " + stepExecution.getSkipCount() + "\n"); protocol.append("Rollbacks: " + stepExecution.getRollbackCount() + "\n"); protocol.append("Filter: " + stepExecution.getFilterCount() + "\n"); protocol.append("+++++++++++++++++++++++++++++++++++++++++++++++++++++++ \n"); } LOGGER.info(protocol.toString()); }
private List<Object[]> buildStepExecutionParameters(StepExecution stepExecution) { Assert.isNull( stepExecution.getId(), "to-be-saved (not updated) StepExecution can't already have an id assigned"); Assert.isNull( stepExecution.getVersion(), "to-be-saved (not updated) StepExecution can't already have a version assigned"); validateStepExecution(stepExecution); stepExecution.setId(stepExecutionIncrementer.nextLongValue()); stepExecution.incrementVersion(); // Should be 0 List<Object[]> parameters = new ArrayList<Object[]>(); String exitDescription = truncateExitDescription(stepExecution.getExitStatus().getExitDescription()); Object[] parameterValues = new Object[] { stepExecution.getId(), stepExecution.getVersion(), stepExecution.getStepName(), stepExecution.getJobExecutionId(), stepExecution.getStartTime(), stepExecution.getEndTime(), stepExecution.getStatus().toString(), stepExecution.getCommitCount(), stepExecution.getReadCount(), stepExecution.getFilterCount(), stepExecution.getWriteCount(), stepExecution.getExitStatus().getExitCode(), exitDescription, stepExecution.getReadSkipCount(), stepExecution.getWriteSkipCount(), stepExecution.getProcessSkipCount(), stepExecution.getRollbackCount(), stepExecution.getLastUpdated() }; Integer[] parameterTypes = new Integer[] { Types.BIGINT, Types.INTEGER, Types.VARCHAR, Types.BIGINT, Types.TIMESTAMP, Types.TIMESTAMP, Types.VARCHAR, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.VARCHAR, Types.VARCHAR, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.TIMESTAMP }; parameters.add(0, Arrays.copyOf(parameterValues, parameterValues.length)); parameters.add(1, Arrays.copyOf(parameterTypes, parameterTypes.length)); return parameters; }
@Override public void updateStepExecution(StepExecution stepExecution) { validateStepExecution(stepExecution); Assert.notNull( stepExecution.getId(), "StepExecution Id cannot be null. StepExecution must saved" + " before it can be updated."); // Do not check for existence of step execution considering // it is saved at every commit point. String exitDescription = truncateExitDescription(stepExecution.getExitStatus().getExitDescription()); // Attempt to prevent concurrent modification errors by blocking here if // someone is already trying to do it. synchronized (stepExecution) { Integer version = stepExecution.getVersion() + 1; Object[] parameters = new Object[] { stepExecution.getStartTime(), stepExecution.getEndTime(), stepExecution.getStatus().toString(), stepExecution.getCommitCount(), stepExecution.getReadCount(), stepExecution.getFilterCount(), stepExecution.getWriteCount(), stepExecution.getExitStatus().getExitCode(), exitDescription, version, stepExecution.getReadSkipCount(), stepExecution.getProcessSkipCount(), stepExecution.getWriteSkipCount(), stepExecution.getRollbackCount(), stepExecution.getLastUpdated(), stepExecution.getId(), stepExecution.getVersion() }; int count = getJdbcTemplate() .update( getQuery(UPDATE_STEP_EXECUTION), parameters, new int[] { Types.TIMESTAMP, Types.TIMESTAMP, Types.VARCHAR, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.VARCHAR, Types.VARCHAR, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.TIMESTAMP, Types.BIGINT, Types.INTEGER }); // Avoid concurrent modifications... if (count == 0) { int curentVersion = getJdbcTemplate() .queryForObject( getQuery(CURRENT_VERSION_STEP_EXECUTION), new Object[] {stepExecution.getId()}, Integer.class); throw new OptimisticLockingFailureException( "Attempt to update step execution id=" + stepExecution.getId() + " with wrong version (" + stepExecution.getVersion() + "), where current version is " + curentVersion); } stepExecution.incrementVersion(); } }