diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBean.java index 77b4703c1..4951a8c68 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBean.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBean.java @@ -399,6 +399,14 @@ class StepParserStepFactoryBean implements FactoryBean, BeanNameAware { if (tasklet != null) { ts.setTasklet(tasklet); } + if (taskExecutor != null) { + TaskExecutorRepeatTemplate repeatTemplate = new TaskExecutorRepeatTemplate(); + repeatTemplate.setTaskExecutor(taskExecutor); + if (throttleLimit != null) { + repeatTemplate.setThrottleLimit(throttleLimit); + } + ts.setStepOperations(repeatTemplate); + } if (transactionManager != null) { ts.setTransactionManager(transactionManager); } 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 ec981c68d..974ca3000 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 @@ -96,7 +96,7 @@ public class TaskletStep extends AbstractStep { private Tasklet tasklet; - private Semaphore semaphore = new Semaphore(1); + private final Semaphore semaphore = new Semaphore(1); /** * Default constructor. @@ -121,7 +121,7 @@ public class TaskletStep extends AbstractStep { @Override public void afterPropertiesSet() throws Exception { super.afterPropertiesSet(); - Assert.state(transactionManager!=null, "A transaction manager must be provided"); + Assert.state(transactionManager != null, "A transaction manager must be provided"); } /** @@ -316,24 +316,29 @@ public class TaskletStep extends AbstractStep { @Override public void afterCompletion(int status) { - if (status != TransactionSynchronization.STATUS_COMMITTED) { - if (oldVersion != null) { - // Wah! the commit failed. We need to rescue the step - // execution data. - stepExecution.setVersion(oldVersion); + try { + if (status != TransactionSynchronization.STATUS_COMMITTED) { + if (oldVersion != null) { + // Wah! the commit failed. We need to rescue the step + // execution data. + stepExecution.setVersion(oldVersion); + } + } + if (status == TransactionSynchronization.STATUS_UNKNOWN) { + logger.error("Rolling back with transaction in unknown state"); + rollback(stepExecution); + stepExecution.upgradeStatus(BatchStatus.UNKNOWN); + stepExecution.setTerminateOnly(); } } - if (status == TransactionSynchronization.STATUS_UNKNOWN) { - logger.error("Rolling back with transaction in unknown state"); - rollback(stepExecution); - stepExecution.upgradeStatus(BatchStatus.UNKNOWN); - stepExecution.setTerminateOnly(); + finally { + // Only release the lock if we acquired it, and release as late + // as possible + if (locked) { + semaphore.release(); + } + locked = false; } - // Only release the lock if we acquired it, and release as late as possible - if (locked) { - semaphore.release(); - } - locked = false; } public Object doInTransaction(TransactionStatus status) { diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBeanTests.java index 26b7e2539..c874f11fd 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBeanTests.java @@ -36,8 +36,10 @@ import org.springframework.batch.core.step.tasklet.TaskletStep; import org.springframework.batch.item.ItemStream; import org.springframework.batch.item.file.FlatFileItemReader; import org.springframework.batch.item.support.PassThroughItemProcessor; +import org.springframework.batch.repeat.support.TaskExecutorRepeatTemplate; import org.springframework.batch.retry.listener.RetryListenerSupport; import org.springframework.batch.support.transaction.ResourcelessTransactionManager; +import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.core.task.SyncTaskExecutor; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.transaction.annotation.Isolation; @@ -65,6 +67,17 @@ public class StepParserStepFactoryBeanTests { assertTrue(tasklet instanceof DummyTasklet); } + @Test + public void testOnlyTaskletTaskExecutor() throws Exception { + StepParserStepFactoryBean fb = new StepParserStepFactoryBean(); + fb.setTasklet(new DummyTasklet()); + fb.setTaskExecutor(new SimpleAsyncTaskExecutor()); + Object step = fb.getObject(); + assertTrue(step instanceof TaskletStep); + Object stepOperations = ReflectionTestUtils.getField(step, "stepOperations"); + assertTrue(stepOperations instanceof TaskExecutorRepeatTemplate); + } + @Test(expected = IllegalStateException.class) public void testSkipLimitSet() throws Exception { StepParserStepFactoryBean fb = new StepParserStepFactoryBean();