diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/AbstractBatchConfiguration.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/AbstractBatchConfiguration.java index 5b744e77b..4d75da6ac 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/AbstractBatchConfiguration.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/AbstractBatchConfiguration.java @@ -127,8 +127,7 @@ public abstract class AbstractBatchConfiguration implements InitializingBean { public void afterPropertiesSet() throws Exception { BatchConfigurer batchConfigurer = getOrCreateConfigurer(); this.jobBuilderFactory = new JobBuilderFactory(batchConfigurer.getJobRepository()); - this.stepBuilderFactory = new StepBuilderFactory(batchConfigurer.getJobRepository(), - batchConfigurer.getTransactionManager()); + this.stepBuilderFactory = new StepBuilderFactory(batchConfigurer.getJobRepository()); } /** diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/StepBuilderFactory.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/StepBuilderFactory.java index aa3a8179e..ea56a6ee8 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/StepBuilderFactory.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/StepBuilderFactory.java @@ -21,8 +21,8 @@ import org.springframework.transaction.PlatformTransactionManager; import org.springframework.util.Assert; /** - * Convenient factory for a {@link StepBuilder} which sets the {@link JobRepository} and - * {@link PlatformTransactionManager} automatically. + * Convenient factory for a {@link StepBuilder} which sets the {@link JobRepository} + * automatically. * * @author Dave Syer * @author Mahmoud Ben Hassine @@ -32,31 +32,25 @@ public class StepBuilderFactory { private JobRepository jobRepository; - private PlatformTransactionManager transactionManager; - /** * Constructor for the {@link StepBuilderFactory}. * @param jobRepository The {@link JobRepository} to be used by the builder factory. * Must not be {@code null}. - * @param transactionManager The {@link PlatformTransactionManager} to be used by the - * builder factory. Must not be {@code null}. */ - public StepBuilderFactory(JobRepository jobRepository, PlatformTransactionManager transactionManager) { + public StepBuilderFactory(JobRepository jobRepository) { Assert.notNull(jobRepository, "JobRepository must not be null"); - Assert.notNull(transactionManager, "transactionManager must not be null"); this.jobRepository = jobRepository; - this.transactionManager = transactionManager; } /** - * Creates a step builder and initializes its job repository and transaction manager. - * Note that, if the builder is used to create a @Bean definition, the name of the - * step and the bean name might be different. + * Creates a step builder and initializes its job repository. Note that, if the + * builder is used to create a @Bean definition, the name of the step and the bean + * name might be different. * @param name the name of the step * @return a step builder */ public StepBuilder get(String name) { - return new StepBuilder(name).repository(this.jobRepository).transactionManager(this.transactionManager); + return new StepBuilder(name).repository(this.jobRepository); } } 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 c3e08bf6d..6c505cf20 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 @@ -275,7 +275,6 @@ public class StepParserStepFactoryBean implements FactoryBean, BeanN builder.startLimit(startLimit); } builder.repository(jobRepository); - builder.transactionManager(transactionManager); for (Object listener : stepExecutionListeners) { if (listener instanceof StepExecutionListener) { builder.listener((StepExecutionListener) listener); @@ -454,7 +453,8 @@ public class StepParserStepFactoryBean implements FactoryBean, BeanN * @return a new {@link TaskletStep} */ protected TaskletStep createTaskletStep() { - TaskletStepBuilder builder = new StepBuilder(name).tasklet(tasklet); + TaskletStepBuilder builder = new TaskletStepBuilder(new StepBuilder(name)) + .transactionManager(transactionManager).tasklet(tasklet); enhanceTaskletStepBuilder(builder); return builder.build(); } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java index 231e8508d..31697bc3f 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java @@ -38,6 +38,7 @@ import org.springframework.batch.repeat.support.TaskExecutorRepeatTemplate; import org.springframework.batch.support.ReflectionUtils; import org.springframework.core.task.SyncTaskExecutor; import org.springframework.core.task.TaskExecutor; +import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.interceptor.TransactionAttribute; /** @@ -57,6 +58,8 @@ public abstract class AbstractTaskletStepBuilder streams = new LinkedHashSet<>(); @@ -89,6 +92,10 @@ public abstract class AbstractTaskletStepBuilder extends AbstractTaskletStepBuilder faultTolerant() { diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/StepBuilderHelper.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/StepBuilderHelper.java index a2f63f0f9..1d2c05cdf 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/StepBuilderHelper.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/StepBuilderHelper.java @@ -36,10 +36,11 @@ import java.util.Set; /** * A base class and utility for other step builders providing access to common properties - * like job repository and transaction manager. + * like job repository and listeners. * * @author Dave Syer * @author Michael Minella + * @author Mahmoud Ben Hassine * @since 2.2 */ public abstract class StepBuilderHelper> { @@ -67,11 +68,6 @@ public abstract class StepBuilderHelper> { return self(); } - public B transactionManager(PlatformTransactionManager transactionManager) { - properties.transactionManager = transactionManager; - return self(); - } - public B startLimit(int startLimit) { properties.startLimit = startLimit; return self(); @@ -116,10 +112,6 @@ public abstract class StepBuilderHelper> { return properties.jobRepository; } - protected PlatformTransactionManager getTransactionManager() { - return properties.transactionManager; - } - protected boolean isAllowStartIfComplete() { return properties.allowStartIfComplete != null ? properties.allowStartIfComplete : false; } @@ -145,11 +137,6 @@ public abstract class StepBuilderHelper> { } - if (target instanceof TaskletStep) { - TaskletStep step = (TaskletStep) target; - step.setTransactionManager(properties.transactionManager); - } - } public static class CommonStepProperties { @@ -162,8 +149,6 @@ public abstract class StepBuilderHelper> { private JobRepository jobRepository; - private PlatformTransactionManager transactionManager; - public CommonStepProperties() { } @@ -172,7 +157,6 @@ public abstract class StepBuilderHelper> { this.startLimit = properties.startLimit; this.allowStartIfComplete = properties.allowStartIfComplete; this.jobRepository = properties.jobRepository; - this.transactionManager = properties.transactionManager; this.stepExecutionListeners = new ArrayList<>(properties.stepExecutionListeners); } @@ -184,14 +168,6 @@ public abstract class StepBuilderHelper> { this.jobRepository = jobRepository; } - public PlatformTransactionManager getTransactionManager() { - return transactionManager; - } - - public void setTransactionManager(PlatformTransactionManager transactionManager) { - this.transactionManager = transactionManager; - } - public String getName() { return name; } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/JobBuilderConfigurationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/JobBuilderConfigurationTests.java index b10ef54d6..97e539689 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/JobBuilderConfigurationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/JobBuilderConfigurationTests.java @@ -41,6 +41,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.lang.Nullable; /** @@ -114,6 +115,9 @@ public class JobBuilderConfigurationTests { @Autowired private StepBuilderFactory steps; + @Autowired + private JdbcTransactionManager transactionManager; + @Bean public Job testJob() throws Exception { SimpleJobBuilder builder = jobs.get("test").start(step1()).next(step2()); @@ -122,12 +126,12 @@ public class JobBuilderConfigurationTests { @Bean protected Step step1() throws Exception { - return steps.get("step1").tasklet(tasklet()).build(); + return steps.get("step1").tasklet(tasklet()).transactionManager(this.transactionManager).build(); } @Bean protected Step step2() throws Exception { - return steps.get("step2").tasklet(tasklet()).build(); + return steps.get("step2").tasklet(tasklet()).transactionManager(this.transactionManager).build(); } @Bean @@ -157,6 +161,9 @@ public class JobBuilderConfigurationTests { @Autowired private StepBuilderFactory steps; + @Autowired + private JdbcTransactionManager transactionManager; + @Autowired private Tasklet tasklet; @@ -168,7 +175,7 @@ public class JobBuilderConfigurationTests { @Bean protected Step step3() throws Exception { - return steps.get("step3").tasklet(tasklet).build(); + return steps.get("step3").tasklet(tasklet).transactionManager(this.transactionManager).build(); } } @@ -217,6 +224,9 @@ public class JobBuilderConfigurationTests { @Autowired private StepBuilderFactory steps; + @Autowired + private JdbcTransactionManager transactionManager; + @Bean public Job beansConfigurerJob() throws Exception { SimpleJobBuilder builder = jobs.get("beans").start(step1()); @@ -232,7 +242,7 @@ public class JobBuilderConfigurationTests { public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { return null; } - }).build(); + }).transactionManager(this.transactionManager).build(); } @Bean @@ -252,6 +262,11 @@ public class JobBuilderConfigurationTests { .addScript("/org/springframework/batch/core/schema-hsqldb.sql").generateUniqueName(true).build(); } + @Bean + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/JobLoaderConfigurationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/JobLoaderConfigurationTests.java index e98f46492..864cc0889 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/JobLoaderConfigurationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/JobLoaderConfigurationTests.java @@ -37,6 +37,7 @@ import org.springframework.batch.core.launch.JobLauncher; import org.springframework.batch.core.scope.context.ChunkContext; import org.springframework.batch.core.step.tasklet.Tasklet; import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.batch.support.transaction.ResourcelessTransactionManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; @@ -135,12 +136,14 @@ class JobLoaderConfigurationTests { @Bean protected Step step1() throws Exception { - return steps.get("step1").tasklet(tasklet()).build(); + return steps.get("step1").tasklet(tasklet()).transactionManager(new ResourcelessTransactionManager()) + .build(); } @Bean protected Step step2() throws Exception { - return steps.get("step2").tasklet(tasklet()).build(); + return steps.get("step2").tasklet(tasklet()).transactionManager(new ResourcelessTransactionManager()) + .build(); } @Bean @@ -179,7 +182,7 @@ class JobLoaderConfigurationTests { public RepeatStatus execute(StepContribution contribution, ChunkContext context) throws Exception { return RepeatStatus.FINISHED; } - }).build(); + }).transactionManager(new ResourcelessTransactionManager()).build(); } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowJobBuilderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowJobBuilderTests.java index 7feb030a2..800dca4d7 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowJobBuilderTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowJobBuilderTests.java @@ -55,6 +55,7 @@ import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.lang.Nullable; +import org.springframework.transaction.PlatformTransactionManager; /** * @author Dave Syer @@ -289,16 +290,19 @@ class FlowJobBuilderTests { @Bean @JobScope - public Step step(StepBuilderFactory stepBuilderFactory, + public Step step(StepBuilderFactory stepBuilderFactory, PlatformTransactionManager transactionManager, @Value("#{jobParameters['chunkSize']}") Integer chunkSize) { return stepBuilderFactory.get("step").chunk(chunkSize) - .reader(new ListItemReader<>(Arrays.asList(1, 2, 3, 4))).writer(items -> { + .transactionManager(transactionManager).reader(new ListItemReader<>(Arrays.asList(1, 2, 3, 4))) + .writer(items -> { }).build(); } @Bean - public Job job(JobBuilderFactory jobBuilderFactory) { - return jobBuilderFactory.get("job").flow(step(null, null)).build().build(); + public Job job(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory, + PlatformTransactionManager transactionManager) { + Step step = step(stepBuilderFactory, transactionManager, null); + return jobBuilderFactory.get("job").flow(step).build().build(); } @Bean @@ -307,6 +311,11 @@ class FlowJobBuilderTests { .addScript("/org/springframework/batch/core/schema-hsqldb.sql").generateUniqueName(true).build(); } + @Bean + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/JobBuilderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/JobBuilderTests.java index 5cd6f159f..7b5a3f19e 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/JobBuilderTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/JobBuilderTests.java @@ -36,6 +36,8 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.support.JdbcTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -68,10 +70,12 @@ class JobBuilderTests { static class MyJobConfiguration { @Bean - public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps, + PlatformTransactionManager transactionManager) { return jobs.get("job").listener(new InterfaceBasedJobExecutionListener()) .listener(new AnnotationBasedJobExecutionListener()) - .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED).build()) + .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .transactionManager(transactionManager).build()) .build(); } @@ -81,6 +85,11 @@ class JobBuilderTests { .addScript("/org/springframework/batch/core/schema-hsqldb.sql").generateUniqueName(true).build(); } + @Bean + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + } static class InterfaceBasedJobExecutionListener implements JobExecutionListener { diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/ItemListenerErrorTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/ItemListenerErrorTests.java index 50ca6bc75..666352d8e 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/ItemListenerErrorTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/ItemListenerErrorTests.java @@ -46,9 +46,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.lang.Nullable; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import org.springframework.transaction.PlatformTransactionManager; /** * BATCH-2322 @@ -134,13 +136,13 @@ class ItemListenerErrorTests { } @Bean - public Step step1(StepBuilderFactory stepBuilderFactory, ItemReader fakeItemReader, - ItemProcessor fakeProcessor, ItemWriter fakeItemWriter, - ItemProcessListener itemProcessListener) { + public Step step1(StepBuilderFactory stepBuilderFactory, PlatformTransactionManager transactionManager, + ItemReader fakeItemReader, ItemProcessor fakeProcessor, + ItemWriter fakeItemWriter, ItemProcessListener itemProcessListener) { - return stepBuilderFactory.get("testStep").chunk(10).reader(fakeItemReader) - .processor(fakeProcessor).writer(fakeItemWriter).listener(itemProcessListener).faultTolerant() - .skipLimit(50).skip(RuntimeException.class).build(); + return stepBuilderFactory.get("testStep").chunk(10).transactionManager(transactionManager) + .reader(fakeItemReader).processor(fakeProcessor).writer(fakeItemWriter) + .listener(itemProcessListener).faultTolerant().skipLimit(50).skip(RuntimeException.class).build(); } @Bean @@ -149,6 +151,11 @@ class ItemListenerErrorTests { .addScript("/org/springframework/batch/core/schema-hsqldb.sql").generateUniqueName(true).build(); } + @Bean + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + @Bean public FailingListener itemListener() { return new FailingListener(); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/observability/BatchMetricsTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/observability/BatchMetricsTests.java index 5aee7586a..09c6ae22a 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/observability/BatchMetricsTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/observability/BatchMetricsTests.java @@ -46,6 +46,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.support.JdbcTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -224,20 +226,25 @@ class BatchMetricsTests { private StepBuilderFactory stepBuilderFactory; - public MyJobConfiguration(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory) { + private PlatformTransactionManager transactionManager; + + public MyJobConfiguration(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory, + PlatformTransactionManager transactionManager) { this.jobBuilderFactory = jobBuilderFactory; this.stepBuilderFactory = stepBuilderFactory; + this.transactionManager = transactionManager; } @Bean public Step step1() { return stepBuilderFactory.get("step1").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) - .build(); + .transactionManager(this.transactionManager).build(); } @Bean public Step step2() { return stepBuilderFactory.get("step2").chunk(2) + .transactionManager(this.transactionManager) .reader(new ListItemReader<>(Arrays.asList(1, 2, 3, 4, 5))) .writer(items -> items.forEach(System.out::println)).build(); } @@ -245,6 +252,7 @@ class BatchMetricsTests { @Bean public Step step3() { return stepBuilderFactory.get("step3").chunk(2) + .transactionManager(this.transactionManager) .reader(new ListItemReader<>(Arrays.asList(6, 7, 8, 9, 10))) .writer(items -> items.forEach(System.out::println)).faultTolerant().skip(Exception.class) .skipLimit(3).build(); @@ -266,6 +274,11 @@ class BatchMetricsTests { .addScript("/org/springframework/batch/core/schema-hsqldb.sql").generateUniqueName(true).build(); } + @Bean + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/FaultTolerantStepBuilderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/FaultTolerantStepBuilderTests.java index 833eb1cf9..d00efa350 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/FaultTolerantStepBuilderTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/FaultTolerantStepBuilderTests.java @@ -38,8 +38,9 @@ class FaultTolerantStepBuilderTests { void testAnnotationBasedStepExecutionListenerRegistration() { // given FaultTolerantStepBuilder faultTolerantStepBuilder = new StepBuilder("myStep") - .repository(new DummyJobRepository()).transactionManager(new ResourcelessTransactionManager()) - .chunk(5).reader(new DummyItemReader()).writer(new DummyItemWriter()).faultTolerant() + .repository(new DummyJobRepository()).chunk(5) + .transactionManager(new ResourcelessTransactionManager()).reader(new DummyItemReader()) + .writer(new DummyItemWriter()).faultTolerant() .listener(new StepBuilderTests.AnnotationBasedStepExecutionListener()); // when diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/RegisterMultiListenerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/RegisterMultiListenerTests.java index cc0da6966..2bd23d213 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/RegisterMultiListenerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/RegisterMultiListenerTests.java @@ -52,6 +52,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.support.GenericApplicationContext; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.lang.Nullable; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -201,11 +202,17 @@ class RegisterMultiListenerTests { .setType(EmbeddedDatabaseType.HSQL).generateUniqueName(true).build()); } + @Bean + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + @Override @Bean public Step step() { - return stepBuilders.get("step").listener(listener()).chunk(2).reader(reader()) - .writer(writer()).faultTolerant().skipLimit(1).skip(MySkippableException.class) + return stepBuilders.get("step").listener(listener()).chunk(2) + .transactionManager(transactionManager(dataSource())).reader(reader()).writer(writer()) + .faultTolerant().skipLimit(1).skip(MySkippableException.class) // ChunkListener registered twice for checking BATCH-2149 .listener((ChunkListener) listener()).build(); } @@ -224,11 +231,16 @@ class RegisterMultiListenerTests { .setType(EmbeddedDatabaseType.HSQL).generateUniqueName(true).build()); } + @Bean + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + @Override @Bean public Step step() { - return stepBuilders.get("step").listener(listener()).chunk(2).reader(reader()) - .writer(writer()).build(); + return stepBuilders.get("step").listener(listener()).chunk(2) + .transactionManager(transactionManager(dataSource())).reader(reader()).writer(writer()).build(); } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/StepBuilderTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/StepBuilderTests.java index 3df90204b..e5360173d 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/StepBuilderTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/builder/StepBuilderTests.java @@ -95,7 +95,7 @@ class StepBuilderTests { @Test void test() throws Exception { TaskletStepBuilder builder = new StepBuilder("step").repository(jobRepository) - .transactionManager(transactionManager).tasklet((contribution, chunkContext) -> null); + .tasklet((contribution, chunkContext) -> null).transactionManager(transactionManager); builder.build().execute(execution); assertEquals(BatchStatus.COMPLETED, execution.getStatus()); } @@ -103,8 +103,9 @@ class StepBuilderTests { @Test void testListeners() throws Exception { TaskletStepBuilder builder = new StepBuilder("step").repository(jobRepository) - .transactionManager(transactionManager).listener(new InterfaceBasedStepExecutionListener()) - .listener(new AnnotationBasedStepExecutionListener()).tasklet((contribution, chunkContext) -> null); + .listener(new InterfaceBasedStepExecutionListener()) + .listener(new AnnotationBasedStepExecutionListener()).tasklet((contribution, chunkContext) -> null) + .transactionManager(transactionManager); builder.build().execute(execution); assertEquals(BatchStatus.COMPLETED, execution.getStatus()); assertEquals(1, InterfaceBasedStepExecutionListener.beforeStepCount); @@ -118,7 +119,7 @@ class StepBuilderTests { @Test void testAnnotationBasedChunkListenerForTaskletStep() throws Exception { TaskletStepBuilder builder = new StepBuilder("step").repository(jobRepository) - .transactionManager(transactionManager).tasklet((contribution, chunkContext) -> null) + .tasklet((contribution, chunkContext) -> null).transactionManager(transactionManager) .listener(new AnnotationBasedChunkListener()); builder.build().execute(execution); assertEquals(BatchStatus.COMPLETED, execution.getStatus()); @@ -128,9 +129,9 @@ class StepBuilderTests { @Test void testAnnotationBasedChunkListenerForSimpleTaskletStep() throws Exception { - SimpleStepBuilder builder = new StepBuilder("step").repository(jobRepository) - .transactionManager(transactionManager).chunk(5).reader(new DummyItemReader()) - .writer(new DummyItemWriter()).listener(new AnnotationBasedChunkListener()); + SimpleStepBuilder builder = new StepBuilder("step").repository(jobRepository).chunk(5) + .transactionManager(transactionManager).reader(new DummyItemReader()).writer(new DummyItemWriter()) + .listener(new AnnotationBasedChunkListener()); builder.build().execute(execution); assertEquals(BatchStatus.COMPLETED, execution.getStatus()); assertEquals(1, AnnotationBasedChunkListener.beforeChunkCount); @@ -139,13 +140,13 @@ class StepBuilderTests { @Test void testAnnotationBasedChunkListenerForFaultTolerantTaskletStep() throws Exception { - SimpleStepBuilder builder = new StepBuilder("step").repository(jobRepository) - .transactionManager(transactionManager).chunk(5).reader(new DummyItemReader()) - .writer(new DummyItemWriter()).faultTolerant().listener(new AnnotationBasedChunkListener()); // TODO// - // should - // this - // return - // FaultTolerantStepBuilder? + SimpleStepBuilder builder = new StepBuilder("step").repository(jobRepository).chunk(5) + .transactionManager(transactionManager).reader(new DummyItemReader()).writer(new DummyItemWriter()) + .faultTolerant().listener(new AnnotationBasedChunkListener()); // TODO// + // should + // this + // return + // FaultTolerantStepBuilder? builder.build().execute(execution); assertEquals(BatchStatus.COMPLETED, execution.getStatus()); assertEquals(1, AnnotationBasedChunkListener.beforeChunkCount); @@ -156,8 +157,8 @@ class StepBuilderTests { void testAnnotationBasedChunkListenerForJobStepBuilder() throws Exception { SimpleJob job = new SimpleJob("job"); job.setJobRepository(jobRepository); - JobStepBuilder builder = new StepBuilder("step").repository(jobRepository) - .transactionManager(transactionManager).job(job).listener(new AnnotationBasedChunkListener()); + JobStepBuilder builder = new StepBuilder("step").repository(jobRepository).job(job) + .listener(new AnnotationBasedChunkListener()); builder.build().execute(execution); assertEquals(BatchStatus.COMPLETED, execution.getStatus()); @@ -174,7 +175,7 @@ class StepBuilderTests { ItemReader reader = new ListItemReader<>(items); SimpleStepBuilder builder = new StepBuilder("step").repository(jobRepository) - .transactionManager(transactionManager).chunk(3).reader(reader) + .chunk(3).transactionManager(transactionManager).reader(reader) .processor(new PassThroughItemProcessor<>()).writer(new DummyItemWriter()) .listener(new AnnotationBasedStepExecutionListener()); builder.build().execute(execution); @@ -209,7 +210,7 @@ class StepBuilderTests { ListItemWriter itemWriter = new ListItemWriter<>(); SimpleStepBuilder builder = new StepBuilder("step").repository(jobRepository) - .transactionManager(transactionManager).chunk(3).reader(reader) + .chunk(3).transactionManager(transactionManager).reader(reader) .processor(Object::toString).writer(itemWriter).listener(new AnnotationBasedStepExecutionListener()); if (faultTolerantStep) { @@ -291,7 +292,7 @@ class StepBuilderTests { ItemReader reader = new ListItemReader<>(items); SimpleStepBuilder builder = new StepBuilder("step").repository(jobRepository) - .transactionManager(transactionManager).chunk(3).reader(reader) + .chunk(3).transactionManager(transactionManager).reader(reader) .writer(new DummyItemWriter()); configurer.apply(builder).listener(new InterfaceBasedItemReadListenerListener()).build().execute(execution); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/concurrent/ConcurrentTransactionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/concurrent/ConcurrentTransactionTests.java index 107ea8dda..0e76e6716 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/test/concurrent/ConcurrentTransactionTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/concurrent/ConcurrentTransactionTests.java @@ -53,9 +53,11 @@ import org.springframework.jdbc.datasource.embedded.ConnectionProperties; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseConfigurer; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.lang.Nullable; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.Isolation; import org.springframework.util.ClassUtils; @@ -94,8 +96,8 @@ class ConcurrentTransactionTests { @Autowired private StepBuilderFactory stepBuilderFactory; - public ConcurrentJobConfiguration(DataSource dataSource) { - super(dataSource); + public ConcurrentJobConfiguration(DataSource dataSource, PlatformTransactionManager transactionManager) { + super(dataSource, transactionManager); } @Bean @@ -111,13 +113,15 @@ class ConcurrentTransactionTests { public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { return RepeatStatus.FINISHED; } - }).build()).next(stepBuilderFactory.get("flow.step2").tasklet(new Tasklet() { - @Nullable - @Override - public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { - return RepeatStatus.FINISHED; - } - }).build()).build(); + }).transactionManager(getTransactionManager()).build()) + .next(stepBuilderFactory.get("flow.step2").tasklet(new Tasklet() { + @Nullable + @Override + public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) + throws Exception { + return RepeatStatus.FINISHED; + } + }).transactionManager(getTransactionManager()).build()).build(); } @Bean @@ -129,7 +133,7 @@ class ConcurrentTransactionTests { System.out.println(">> Beginning concurrent job test"); return RepeatStatus.FINISHED; } - }).build(); + }).transactionManager(getTransactionManager()).build(); } @Bean @@ -141,7 +145,7 @@ class ConcurrentTransactionTests { System.out.println(">> Ending concurrent job test"); return RepeatStatus.FINISHED; } - }).build(); + }).transactionManager(getTransactionManager()).build(); } @Bean @@ -223,6 +227,11 @@ class ConcurrentTransactionTests { return embeddedDatabaseFactory.getDatabase(); } + @Bean + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/Db2JobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/Db2JobRepositoryIntegrationTests.java index bcf3e9fd4..53894fbcf 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/Db2JobRepositoryIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/Db2JobRepositoryIntegrationTests.java @@ -40,7 +40,9 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import org.springframework.transaction.PlatformTransactionManager; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -105,9 +107,16 @@ class Db2JobRepositoryIntegrationTests { } @Bean - public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps, + PlatformTransactionManager transactionManager) { return jobs.get("job") - .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED).build()) + .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .transactionManager(transactionManager).build()) .build(); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/DerbyJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/DerbyJobRepositoryIntegrationTests.java index 9b069a7cc..ec505b1b6 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/DerbyJobRepositoryIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/DerbyJobRepositoryIntegrationTests.java @@ -34,7 +34,9 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import org.springframework.transaction.PlatformTransactionManager; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -75,9 +77,16 @@ class DerbyJobRepositoryIntegrationTests { } @Bean - public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps, + PlatformTransactionManager transactionManager) { return jobs.get("job") - .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED).build()) + .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .transactionManager(transactionManager).build()) .build(); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/H2CompatibilityModeJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/H2CompatibilityModeJobRepositoryIntegrationTests.java index f21c62a55..de54ec273 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/H2CompatibilityModeJobRepositoryIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/H2CompatibilityModeJobRepositoryIntegrationTests.java @@ -39,12 +39,15 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.SimpleDriverDataSource; import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.jdbc.support.JdbcTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; /** * @author Henning Pƶttker + * @author Mahmoud Ben Hassine */ class H2CompatibilityModeJobRepositoryIntegrationTests { @@ -83,9 +86,15 @@ class H2CompatibilityModeJobRepositoryIntegrationTests { static class TestConfiguration { @Bean - Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + + @Bean + Job job(JobBuilderFactory jobs, StepBuilderFactory steps, PlatformTransactionManager transactionManager) { return jobs.get("job") - .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED).build()) + .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .transactionManager(transactionManager).build()) .build(); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/H2JobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/H2JobRepositoryIntegrationTests.java index 3f55519e4..7281108cf 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/H2JobRepositoryIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/H2JobRepositoryIntegrationTests.java @@ -34,7 +34,9 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import org.springframework.transaction.PlatformTransactionManager; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -75,9 +77,16 @@ class H2JobRepositoryIntegrationTests { } @Bean - public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps, + PlatformTransactionManager transactionManager) { return jobs.get("job") - .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED).build()) + .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .transactionManager(transactionManager).build()) .build(); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/HSQLDBJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/HSQLDBJobRepositoryIntegrationTests.java index eecdd73aa..d65085fab 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/HSQLDBJobRepositoryIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/HSQLDBJobRepositoryIntegrationTests.java @@ -34,7 +34,9 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import org.springframework.transaction.PlatformTransactionManager; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -75,9 +77,16 @@ class HSQLDBJobRepositoryIntegrationTests { } @Bean - public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps, + PlatformTransactionManager transactionManager) { return jobs.get("job") - .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED).build()) + .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .transactionManager(transactionManager).build()) .build(); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/MySQLJdbcJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/MySQLJdbcJobRepositoryIntegrationTests.java index a73f8f347..6eba4326d 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/MySQLJdbcJobRepositoryIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/MySQLJdbcJobRepositoryIntegrationTests.java @@ -47,7 +47,9 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import org.springframework.transaction.PlatformTransactionManager; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -131,10 +133,16 @@ class MySQLJdbcJobRepositoryIntegrationTests { } @Bean - public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps, + PlatformTransactionManager transactionManager) { return jobs.get("job").start(steps.get("step").tasklet((contribution, chunkContext) -> { throw new Exception("expected failure"); - }).build()).build(); + }).transactionManager(transactionManager).build()).build(); } @Bean diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/MySQLJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/MySQLJobRepositoryIntegrationTests.java index 524e586e0..2f19a4cc7 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/MySQLJobRepositoryIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/MySQLJobRepositoryIntegrationTests.java @@ -40,7 +40,9 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import org.springframework.transaction.PlatformTransactionManager; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -102,9 +104,16 @@ class MySQLJobRepositoryIntegrationTests { } @Bean - public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps, + PlatformTransactionManager transactionManager) { return jobs.get("job") - .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED).build()) + .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .transactionManager(transactionManager).build()) .build(); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/PostgreSQLJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/PostgreSQLJobRepositoryIntegrationTests.java index 7ba2d27bc..7ea53c9e1 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/PostgreSQLJobRepositoryIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/PostgreSQLJobRepositoryIntegrationTests.java @@ -40,7 +40,9 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import org.springframework.transaction.PlatformTransactionManager; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -101,9 +103,16 @@ class PostgreSQLJobRepositoryIntegrationTests { } @Bean - public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps, + PlatformTransactionManager transactionManager) { return jobs.get("job") - .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED).build()) + .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .transactionManager(transactionManager).build()) .build(); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/SQLServerJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/SQLServerJobRepositoryIntegrationTests.java index 1c9d8b312..26387f6e8 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/SQLServerJobRepositoryIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/SQLServerJobRepositoryIntegrationTests.java @@ -40,7 +40,9 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import org.springframework.transaction.PlatformTransactionManager; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -102,9 +104,16 @@ class SQLServerJobRepositoryIntegrationTests { } @Bean - public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps, + PlatformTransactionManager transactionManager) { return jobs.get("job") - .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED).build()) + .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .transactionManager(transactionManager).build()) .build(); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/SQLiteJobRepositoryIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/SQLiteJobRepositoryIntegrationTests.java index 2aa5a4d6c..05a76fe17 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/SQLiteJobRepositoryIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/repository/SQLiteJobRepositoryIntegrationTests.java @@ -35,7 +35,9 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import org.springframework.transaction.PlatformTransactionManager; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -82,9 +84,16 @@ class SQLiteJobRepositoryIntegrationTests { } @Bean - public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) { + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + + @Bean + public Job job(JobBuilderFactory jobs, StepBuilderFactory steps, + PlatformTransactionManager transactionManager) { return jobs.get("job") - .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED).build()) + .start(steps.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .transactionManager(transactionManager).build()) .build(); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/test/step/FaultTolerantStepIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/test/step/FaultTolerantStepIntegrationTests.java index 14611d328..4eb34611e 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/test/step/FaultTolerantStepIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/test/step/FaultTolerantStepIntegrationTests.java @@ -77,8 +77,8 @@ class FaultTolerantStepIntegrationTests { } }; skipPolicy = new SkipIllegalArgumentExceptionSkipPolicy(); - stepBuilder = new StepBuilderFactory(jobRepository, transactionManager).get("step") - .chunk(CHUNK_SIZE).reader(itemReader).processor(item -> item > 20 ? null : item) + stepBuilder = new StepBuilderFactory(jobRepository).get("step").chunk(CHUNK_SIZE) + .transactionManager(transactionManager).reader(itemReader).processor(item -> item > 20 ? null : item) .writer(itemWriter).faultTolerant(); } @@ -178,9 +178,9 @@ class FaultTolerantStepIntegrationTests { } }; - Step step = new StepBuilderFactory(jobRepository, transactionManager).get("step").chunk(5) - .reader(itemReader).processor(itemProcessor).writer(itemWriter).faultTolerant().skip(Exception.class) - .skipLimit(3).build(); + Step step = new StepBuilderFactory(jobRepository).get("step").chunk(5) + .transactionManager(transactionManager).reader(itemReader).processor(itemProcessor).writer(itemWriter) + .faultTolerant().skip(Exception.class).skipLimit(3).build(); // When StepExecution stepExecution = execute(step); @@ -218,9 +218,9 @@ class FaultTolerantStepIntegrationTests { } }; - Step step = new StepBuilderFactory(jobRepository, transactionManager).get("step").chunk(5) - .reader(itemReader).processor(itemProcessor).writer(itemWriter).faultTolerant() - .skipPolicy(new AlwaysSkipItemSkipPolicy()).build(); + Step step = new StepBuilderFactory(jobRepository).get("step").chunk(5) + .transactionManager(transactionManager).reader(itemReader).processor(itemProcessor).writer(itemWriter) + .faultTolerant().skipPolicy(new AlwaysSkipItemSkipPolicy()).build(); // When StepExecution stepExecution = execute(step); diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/annotation/BatchIntegrationConfiguration.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/annotation/BatchIntegrationConfiguration.java index 192adb107..7e16563d9 100644 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/annotation/BatchIntegrationConfiguration.java +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/config/annotation/BatchIntegrationConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -85,9 +85,9 @@ public class BatchIntegrationConfiguration implements InitializingBean { this.transactionManager); this.remoteChunkingWorkerBuilder = new RemoteChunkingWorkerBuilder<>(); this.remotePartitioningManagerStepBuilderFactory = new RemotePartitioningManagerStepBuilderFactory( - this.jobRepository, this.jobExplorer, this.transactionManager); + this.jobRepository, this.jobExplorer); this.remotePartitioningWorkerStepBuilderFactory = new RemotePartitioningWorkerStepBuilderFactory( - this.jobRepository, this.jobExplorer, this.transactionManager); + this.jobRepository, this.jobExplorer); } } diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilder.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilder.java index 46118d485..f34d7fdfb 100644 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilder.java +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilder.java @@ -234,12 +234,6 @@ public class RemotePartitioningManagerStepBuilder extends PartitionStepBuilder { return this; } - @Override - public RemotePartitioningManagerStepBuilder transactionManager(PlatformTransactionManager transactionManager) { - super.transactionManager(transactionManager); - return this; - } - @Override public RemotePartitioningManagerStepBuilder partitioner(String workerStepName, Partitioner partitioner) { super.partitioner(workerStepName, partitioner); diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilderFactory.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilderFactory.java index 1f3b4afc1..37d54ca82 100644 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilderFactory.java +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningManagerStepBuilderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,20 +39,15 @@ public class RemotePartitioningManagerStepBuilderFactory implements BeanFactoryA final private JobRepository jobRepository; - final private PlatformTransactionManager transactionManager; - /** * Create a new {@link RemotePartitioningManagerStepBuilderFactory}. * @param jobRepository the job repository to use * @param jobExplorer the job explorer to use - * @param transactionManager the transaction manager to use */ - public RemotePartitioningManagerStepBuilderFactory(JobRepository jobRepository, JobExplorer jobExplorer, - PlatformTransactionManager transactionManager) { + public RemotePartitioningManagerStepBuilderFactory(JobRepository jobRepository, JobExplorer jobExplorer) { this.jobRepository = jobRepository; this.jobExplorer = jobExplorer; - this.transactionManager = transactionManager; } @Override @@ -68,8 +63,7 @@ public class RemotePartitioningManagerStepBuilderFactory implements BeanFactoryA */ public RemotePartitioningManagerStepBuilder get(String name) { return new RemotePartitioningManagerStepBuilder(name).repository(this.jobRepository) - .jobExplorer(this.jobExplorer).beanFactory(this.beanFactory) - .transactionManager(this.transactionManager); + .jobExplorer(this.jobExplorer).beanFactory(this.beanFactory); } } diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningWorkerStepBuilder.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningWorkerStepBuilder.java index 999afa25b..d207fa3ff 100644 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningWorkerStepBuilder.java +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningWorkerStepBuilder.java @@ -150,12 +150,6 @@ public class RemotePartitioningWorkerStepBuilder extends StepBuilder { return this; } - @Override - public RemotePartitioningWorkerStepBuilder transactionManager(PlatformTransactionManager transactionManager) { - super.transactionManager(transactionManager); - return this; - } - @Override public RemotePartitioningWorkerStepBuilder startLimit(int startLimit) { super.startLimit(startLimit); diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningWorkerStepBuilderFactory.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningWorkerStepBuilderFactory.java index 601d878ef..cd2c0d6e0 100644 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningWorkerStepBuilderFactory.java +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/partition/RemotePartitioningWorkerStepBuilderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,20 +39,15 @@ public class RemotePartitioningWorkerStepBuilderFactory implements BeanFactoryAw final private JobRepository jobRepository; - final private PlatformTransactionManager transactionManager; - /** * Create a new {@link RemotePartitioningWorkerStepBuilderFactory}. * @param jobRepository the job repository to use * @param jobExplorer the job explorer to use - * @param transactionManager the transaction manager to use */ - public RemotePartitioningWorkerStepBuilderFactory(JobRepository jobRepository, JobExplorer jobExplorer, - PlatformTransactionManager transactionManager) { + public RemotePartitioningWorkerStepBuilderFactory(JobRepository jobRepository, JobExplorer jobExplorer) { this.jobExplorer = jobExplorer; this.jobRepository = jobRepository; - this.transactionManager = transactionManager; } @Override @@ -68,8 +63,7 @@ public class RemotePartitioningWorkerStepBuilderFactory implements BeanFactoryAw */ public RemotePartitioningWorkerStepBuilder get(String name) { return new RemotePartitioningWorkerStepBuilder(name).repository(this.jobRepository) - .jobExplorer(this.jobExplorer).beanFactory(this.beanFactory) - .transactionManager(this.transactionManager); + .jobExplorer(this.jobExplorer).beanFactory(this.beanFactory); } } diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/config/DataSourceConfiguration.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/config/DataSourceConfiguration.java index 758bb2a4b..a21d44871 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/config/DataSourceConfiguration.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/config/DataSourceConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ import org.springframework.core.env.Environment; import org.springframework.core.io.ResourceLoader; import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.jdbc.support.JdbcTransactionManager; /** * @author Dave Syer @@ -62,4 +63,9 @@ public class DataSourceConfiguration { return dataSource; } + @Bean + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + } \ No newline at end of file diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/config/RetrySampleConfiguration.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/config/RetrySampleConfiguration.java index 717fc850e..eb38f8a10 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/config/RetrySampleConfiguration.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/config/RetrySampleConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ import org.springframework.batch.sample.support.RetrySampleItemWriter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.PlatformTransactionManager; /** * @author Dave Syer @@ -44,6 +45,9 @@ public class RetrySampleConfiguration { @Autowired private StepBuilderFactory steps; + @Autowired + private PlatformTransactionManager transactionManager; + @Bean public Job retrySample() { return jobs.get("retrySample").start(step()).build(); @@ -51,8 +55,8 @@ public class RetrySampleConfiguration { @Bean protected Step step() { - return steps.get("step").chunk(1).reader(reader()).writer(writer()).faultTolerant() - .retry(Exception.class).retryLimit(3).build(); + return steps.get("step").chunk(1).transactionManager(this.transactionManager).reader(reader()) + .writer(writer()).faultTolerant().retry(Exception.class).retryLimit(3).build(); } @Bean diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/remotepartitioning/aggregating/WorkerConfiguration.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/remotepartitioning/aggregating/WorkerConfiguration.java index d372fe61f..b0306f1c5 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/remotepartitioning/aggregating/WorkerConfiguration.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/remotepartitioning/aggregating/WorkerConfiguration.java @@ -33,6 +33,7 @@ import org.springframework.context.annotation.Import; import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.dsl.IntegrationFlow; import org.springframework.integration.jms.dsl.Jms; +import org.springframework.transaction.PlatformTransactionManager; /** * This configuration class is for the worker side of the remote partitioning sample. Each @@ -84,9 +85,9 @@ public class WorkerConfiguration { * Configure the worker step */ @Bean - public Step workerStep() { + public Step workerStep(PlatformTransactionManager transactionManager) { return this.workerStepBuilderFactory.get("workerStep").inputChannel(requests()).outputChannel(replies()) - .tasklet(tasklet(null)).build(); + .tasklet(tasklet(null)).transactionManager(transactionManager).build(); } @Bean diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/remotepartitioning/polling/WorkerConfiguration.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/remotepartitioning/polling/WorkerConfiguration.java index 8b9fe42b4..e4e146daf 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/remotepartitioning/polling/WorkerConfiguration.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/remotepartitioning/polling/WorkerConfiguration.java @@ -33,6 +33,7 @@ import org.springframework.context.annotation.Import; import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.dsl.IntegrationFlow; import org.springframework.integration.jms.dsl.Jms; +import org.springframework.transaction.PlatformTransactionManager; /** * This configuration class is for the worker side of the remote partitioning sample. Each @@ -70,8 +71,9 @@ public class WorkerConfiguration { * Configure the worker step */ @Bean - public Step workerStep() { - return this.workerStepBuilderFactory.get("workerStep").inputChannel(requests()).tasklet(tasklet(null)).build(); + public Step workerStep(PlatformTransactionManager transactionManager) { + return this.workerStepBuilderFactory.get("workerStep").inputChannel(requests()).tasklet(tasklet(null)) + .transactionManager(transactionManager).build(); } @Bean diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/skip/DataSourceConfiguration.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/skip/DataSourceConfiguration.java index 2feaa1c8e..0cddf5004 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/skip/DataSourceConfiguration.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/skip/DataSourceConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import javax.sql.DataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.support.JdbcTransactionManager; @Configuration public class DataSourceConfiguration { @@ -30,4 +31,9 @@ public class DataSourceConfiguration { .addScript("/org/springframework/batch/core/schema-hsqldb.sql").generateUniqueName(true).build(); } + @Bean + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + } \ No newline at end of file diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/skip/SkippableExceptionDuringProcessSample.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/skip/SkippableExceptionDuringProcessSample.java index 2609fdb10..c330b89a7 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/skip/SkippableExceptionDuringProcessSample.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/skip/SkippableExceptionDuringProcessSample.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ import org.springframework.batch.item.support.ListItemReader; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.transaction.PlatformTransactionManager; /** * @author Mahmoud Ben Hassine @@ -43,10 +44,13 @@ public class SkippableExceptionDuringProcessSample { private final StepBuilderFactory stepBuilderFactory; + private final PlatformTransactionManager transactionManager; + public SkippableExceptionDuringProcessSample(JobBuilderFactory jobBuilderFactory, - StepBuilderFactory stepBuilderFactory) { + StepBuilderFactory stepBuilderFactory, PlatformTransactionManager transactionManager) { this.jobBuilderFactory = jobBuilderFactory; this.stepBuilderFactory = stepBuilderFactory; + this.transactionManager = transactionManager; } @Bean @@ -85,9 +89,9 @@ public class SkippableExceptionDuringProcessSample { @Bean public Step step() { - return this.stepBuilderFactory.get("step").chunk(3).reader(itemReader()) - .processor(itemProcessor()).writer(itemWriter()).faultTolerant().skip(IllegalArgumentException.class) - .skipLimit(3).build(); + return this.stepBuilderFactory.get("step").chunk(3) + .transactionManager(this.transactionManager).reader(itemReader()).processor(itemProcessor()) + .writer(itemWriter()).faultTolerant().skip(IllegalArgumentException.class).skipLimit(3).build(); } @Bean diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/skip/SkippableExceptionDuringReadSample.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/skip/SkippableExceptionDuringReadSample.java index 8f15f901e..64220bcd6 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/skip/SkippableExceptionDuringReadSample.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/skip/SkippableExceptionDuringReadSample.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ import org.springframework.batch.item.support.ListItemReader; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.transaction.PlatformTransactionManager; /** * @author Mahmoud Ben Hassine @@ -43,10 +44,13 @@ public class SkippableExceptionDuringReadSample { private final StepBuilderFactory stepBuilderFactory; + private final PlatformTransactionManager transactionManager; + public SkippableExceptionDuringReadSample(JobBuilderFactory jobBuilderFactory, - StepBuilderFactory stepBuilderFactory) { + StepBuilderFactory stepBuilderFactory, PlatformTransactionManager transactionManager) { this.jobBuilderFactory = jobBuilderFactory; this.stepBuilderFactory = stepBuilderFactory; + this.transactionManager = transactionManager; } @Bean @@ -85,9 +89,9 @@ public class SkippableExceptionDuringReadSample { @Bean public Step step() { - return this.stepBuilderFactory.get("step").chunk(3).reader(itemReader()) - .processor(itemProcessor()).writer(itemWriter()).faultTolerant().skip(IllegalArgumentException.class) - .skipLimit(3).build(); + return this.stepBuilderFactory.get("step").chunk(3) + .transactionManager(this.transactionManager).reader(itemReader()).processor(itemProcessor()) + .writer(itemWriter()).faultTolerant().skip(IllegalArgumentException.class).skipLimit(3).build(); } @Bean diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/skip/SkippableExceptionDuringWriteSample.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/skip/SkippableExceptionDuringWriteSample.java index b4298051c..3db58e398 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/skip/SkippableExceptionDuringWriteSample.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/skip/SkippableExceptionDuringWriteSample.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ import org.springframework.batch.item.support.ListItemReader; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.transaction.PlatformTransactionManager; /** * @author Mahmoud Ben Hassine @@ -43,10 +44,13 @@ public class SkippableExceptionDuringWriteSample { private final StepBuilderFactory stepBuilderFactory; + private final PlatformTransactionManager transactionManager; + public SkippableExceptionDuringWriteSample(JobBuilderFactory jobBuilderFactory, - StepBuilderFactory stepBuilderFactory) { + StepBuilderFactory stepBuilderFactory, PlatformTransactionManager transactionManager) { this.jobBuilderFactory = jobBuilderFactory; this.stepBuilderFactory = stepBuilderFactory; + this.transactionManager = transactionManager; } @Bean @@ -85,9 +89,9 @@ public class SkippableExceptionDuringWriteSample { @Bean public Step step() { - return this.stepBuilderFactory.get("step").chunk(3).reader(itemReader()) - .processor(itemProcessor()).writer(itemWriter()).faultTolerant().skip(IllegalArgumentException.class) - .skipLimit(3).build(); + return this.stepBuilderFactory.get("step").chunk(3) + .transactionManager(this.transactionManager).reader(itemReader()).processor(itemProcessor()) + .writer(itemWriter()).faultTolerant().skip(IllegalArgumentException.class).skipLimit(3).build(); } @Bean diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/validation/ValidationSampleConfiguration.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/validation/ValidationSampleConfiguration.java index 50c38f1de..d33163668 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/validation/ValidationSampleConfiguration.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/validation/ValidationSampleConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.support.JdbcTransactionManager; /** * @author Mahmoud Ben Hassine @@ -70,8 +71,8 @@ public class ValidationSampleConfiguration { @Bean public Step step() throws Exception { - return this.steps.get("step").chunk(1).reader(itemReader()).processor(itemValidator()) - .writer(itemWriter()).build(); + return this.steps.get("step").chunk(1).transactionManager(transactionManager(dataSource())) + .reader(itemReader()).processor(itemValidator()).writer(itemWriter()).build(); } @Bean @@ -85,4 +86,9 @@ public class ValidationSampleConfiguration { .addScript("/org/springframework/batch/core/schema-hsqldb.sql").generateUniqueName(true).build(); } + @Bean + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + } diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/JsonSupportIntegrationTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/JsonSupportIntegrationTests.java index 7445594e3..a3205bdb3 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/JsonSupportIntegrationTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/JsonSupportIntegrationTests.java @@ -49,6 +49,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.FileSystemResource; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.util.DigestUtils; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -94,7 +95,8 @@ class JsonSupportIntegrationTests { @Bean public Step step() { - return steps.get("step").chunk(2).reader(itemReader()).writer(itemWriter()).build(); + return steps.get("step").chunk(2).transactionManager(transactionManager(dataSource())) + .reader(itemReader()).writer(itemWriter()).build(); } @Bean @@ -108,6 +110,11 @@ class JsonSupportIntegrationTests { .addScript("/org/springframework/batch/core/schema-hsqldb.sql").generateUniqueName(true).build(); } + @Bean + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + } @Test diff --git a/spring-batch-test/src/test/java/org/springframework/batch/test/JobLauncherTestUtilsTests.java b/spring-batch-test/src/test/java/org/springframework/batch/test/JobLauncherTestUtilsTests.java index 947188027..3e37b7de0 100644 --- a/spring-batch-test/src/test/java/org/springframework/batch/test/JobLauncherTestUtilsTests.java +++ b/spring-batch-test/src/test/java/org/springframework/batch/test/JobLauncherTestUtilsTests.java @@ -35,6 +35,7 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.lang.Nullable; import java.util.HashSet; @@ -92,7 +93,7 @@ class JobLauncherTestUtilsTests { public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { return null; } - }).build(); + }).transactionManager(transactionManager(dataSource())).build(); } @Bean @@ -114,6 +115,11 @@ class JobLauncherTestUtilsTests { .addScript("/org/springframework/batch/core/schema-hsqldb.sql").generateUniqueName(true).build(); } + @Bean + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + } } diff --git a/spring-batch-test/src/test/java/org/springframework/batch/test/SpringBatchTestJUnit4Tests.java b/spring-batch-test/src/test/java/org/springframework/batch/test/SpringBatchTestJUnit4Tests.java index 338cf2aa2..25534fd2b 100644 --- a/spring-batch-test/src/test/java/org/springframework/batch/test/SpringBatchTestJUnit4Tests.java +++ b/spring-batch-test/src/test/java/org/springframework/batch/test/SpringBatchTestJUnit4Tests.java @@ -42,6 +42,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; @@ -130,6 +131,11 @@ public class SpringBatchTestJUnit4Tests { .addScript("/org/springframework/batch/core/schema-hsqldb.sql").build(); } + @Bean + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + @Bean @StepScope public ItemReader stepScopedItemReader(@Value("#{stepExecutionContext['input.data']}") String data) { @@ -144,8 +150,11 @@ public class SpringBatchTestJUnit4Tests { @Bean public Job job() { - return this.jobBuilderFactory.get("job").start(this.stepBuilderFactory.get("step") - .tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED).build()).build(); + return this.jobBuilderFactory.get("job") + .start(this.stepBuilderFactory.get("step") + .tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .transactionManager(transactionManager(dataSource())).build()) + .build(); } } diff --git a/spring-batch-test/src/test/java/org/springframework/batch/test/SpringBatchTestJUnit5Tests.java b/spring-batch-test/src/test/java/org/springframework/batch/test/SpringBatchTestJUnit5Tests.java index d7d4e6766..e9e3ff484 100644 --- a/spring-batch-test/src/test/java/org/springframework/batch/test/SpringBatchTestJUnit5Tests.java +++ b/spring-batch-test/src/test/java/org/springframework/batch/test/SpringBatchTestJUnit5Tests.java @@ -43,6 +43,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -124,6 +125,11 @@ public class SpringBatchTestJUnit5Tests { .addScript("/org/springframework/batch/core/schema-hsqldb.sql").build(); } + @Bean + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + @Bean @StepScope public ItemReader stepScopedItemReader(@Value("#{stepExecutionContext['input.data']}") String data) { @@ -138,8 +144,10 @@ public class SpringBatchTestJUnit5Tests { @Bean public Job job(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory) { - return jobBuilderFactory.get("job").start(stepBuilderFactory.get("step") - .tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED).build()).build(); + return jobBuilderFactory.get("job") + .start(stepBuilderFactory.get("step").tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED) + .transactionManager(transactionManager(dataSource())).build()) + .build(); } } diff --git a/spring-batch-test/src/test/java/org/springframework/batch/test/StepScopeAnnotatedListenerIntegrationTests.java b/spring-batch-test/src/test/java/org/springframework/batch/test/StepScopeAnnotatedListenerIntegrationTests.java index 33bdbfaec..278da2a27 100644 --- a/spring-batch-test/src/test/java/org/springframework/batch/test/StepScopeAnnotatedListenerIntegrationTests.java +++ b/spring-batch-test/src/test/java/org/springframework/batch/test/StepScopeAnnotatedListenerIntegrationTests.java @@ -43,8 +43,10 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.jdbc.support.JdbcTransactionManager; import org.springframework.lang.Nullable; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +import org.springframework.transaction.PlatformTransactionManager; @SpringJUnitConfig class StepScopeAnnotatedListenerIntegrationTests { @@ -103,6 +105,9 @@ class StepScopeAnnotatedListenerIntegrationTests { @Autowired private StepBuilderFactory stepBuilder; + @Autowired + private PlatformTransactionManager transactionManager; + @Bean JobLauncherTestUtils jobLauncherTestUtils() { return new JobLauncherTestUtils(); @@ -116,6 +121,11 @@ class StepScopeAnnotatedListenerIntegrationTests { .setType(EmbeddedDatabaseType.HSQL).build(); } + @Bean + public JdbcTransactionManager transactionManager(DataSource dataSource) { + return new JdbcTransactionManager(dataSource); + } + @Bean public Job jobUnderTest() { return jobBuilder.get("job-under-test").start(stepUnderTest()).build(); @@ -123,7 +133,8 @@ class StepScopeAnnotatedListenerIntegrationTests { @Bean public Step stepUnderTest() { - return stepBuilder.get("step-under-test").chunk(1).reader(reader()).processor(processor()) + return stepBuilder.get("step-under-test").chunk(1) + .transactionManager(this.transactionManager).reader(reader()).processor(processor()) .writer(writer()).build(); }