Skip to content

Commit 7c8fb17

Browse files
committed
Move the transaction manager configuration to AbstractTaskletStepBuilder
Before this commit, the transaction manager was configurable at the StepBuilder level, which is inconsistent with the XML config style in addition to be not needed for most step types. This commit moves the configuration of the transaction manager from the StepBuilder down to the AbstractTaskletStepBuilder, which is the level where the transaction manager is needed. Resolves #4130
1 parent 55af86d commit 7c8fb17

File tree

46 files changed

+409
-195
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+409
-195
lines changed

spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/AbstractBatchConfiguration.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,7 @@ public JobRegistry jobRegistry() throws Exception {
127127
public void afterPropertiesSet() throws Exception {
128128
BatchConfigurer batchConfigurer = getOrCreateConfigurer();
129129
this.jobBuilderFactory = new JobBuilderFactory(batchConfigurer.getJobRepository());
130-
this.stepBuilderFactory = new StepBuilderFactory(batchConfigurer.getJobRepository(),
131-
batchConfigurer.getTransactionManager());
130+
this.stepBuilderFactory = new StepBuilderFactory(batchConfigurer.getJobRepository());
132131
}
133132

134133
/**

spring-batch-core/src/main/java/org/springframework/batch/core/configuration/annotation/StepBuilderFactory.java

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
import org.springframework.util.Assert;
2222

2323
/**
24-
* Convenient factory for a {@link StepBuilder} which sets the {@link JobRepository} and
25-
* {@link PlatformTransactionManager} automatically.
24+
* Convenient factory for a {@link StepBuilder} which sets the {@link JobRepository}
25+
* automatically.
2626
*
2727
* @author Dave Syer
2828
* @author Mahmoud Ben Hassine
@@ -32,31 +32,25 @@ public class StepBuilderFactory {
3232

3333
private JobRepository jobRepository;
3434

35-
private PlatformTransactionManager transactionManager;
36-
3735
/**
3836
* Constructor for the {@link StepBuilderFactory}.
3937
* @param jobRepository The {@link JobRepository} to be used by the builder factory.
4038
* Must not be {@code null}.
41-
* @param transactionManager The {@link PlatformTransactionManager} to be used by the
42-
* builder factory. Must not be {@code null}.
4339
*/
44-
public StepBuilderFactory(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
40+
public StepBuilderFactory(JobRepository jobRepository) {
4541
Assert.notNull(jobRepository, "JobRepository must not be null");
46-
Assert.notNull(transactionManager, "transactionManager must not be null");
4742
this.jobRepository = jobRepository;
48-
this.transactionManager = transactionManager;
4943
}
5044

5145
/**
52-
* Creates a step builder and initializes its job repository and transaction manager.
53-
* Note that, if the builder is used to create a @Bean definition, the name of the
54-
* step and the bean name might be different.
46+
* Creates a step builder and initializes its job repository. Note that, if the
47+
* builder is used to create a @Bean definition, the name of the step and the bean
48+
* name might be different.
5549
* @param name the name of the step
5650
* @return a step builder
5751
*/
5852
public StepBuilder get(String name) {
59-
return new StepBuilder(name).repository(this.jobRepository).transactionManager(this.transactionManager);
53+
return new StepBuilder(name).repository(this.jobRepository);
6054
}
6155

6256
}

spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/StepParserStepFactoryBean.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,6 @@ protected void enhanceCommonStep(StepBuilderHelper<?> builder) {
275275
builder.startLimit(startLimit);
276276
}
277277
builder.repository(jobRepository);
278-
builder.transactionManager(transactionManager);
279278
for (Object listener : stepExecutionListeners) {
280279
if (listener instanceof StepExecutionListener) {
281280
builder.listener((StepExecutionListener) listener);
@@ -454,7 +453,8 @@ protected SimpleStepBuilder<I, O> getSimpleStepBuilder(String stepName) {
454453
* @return a new {@link TaskletStep}
455454
*/
456455
protected TaskletStep createTaskletStep() {
457-
TaskletStepBuilder builder = new StepBuilder(name).tasklet(tasklet);
456+
TaskletStepBuilder builder = new TaskletStepBuilder(new StepBuilder(name))
457+
.transactionManager(transactionManager).tasklet(tasklet);
458458
enhanceTaskletStepBuilder(builder);
459459
return builder.build();
460460
}

spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.springframework.batch.support.ReflectionUtils;
3939
import org.springframework.core.task.SyncTaskExecutor;
4040
import org.springframework.core.task.TaskExecutor;
41+
import org.springframework.transaction.PlatformTransactionManager;
4142
import org.springframework.transaction.interceptor.TransactionAttribute;
4243

4344
/**
@@ -57,6 +58,8 @@ public abstract class AbstractTaskletStepBuilder<B extends AbstractTaskletStepBu
5758

5859
private RepeatOperations stepOperations;
5960

61+
private PlatformTransactionManager transactionManager;
62+
6063
private TransactionAttribute transactionAttribute;
6164

6265
private Set<ItemStream> streams = new LinkedHashSet<>();
@@ -89,6 +92,10 @@ public TaskletStep build() {
8992

9093
step.setChunkListeners(chunkListeners.toArray(new ChunkListener[0]));
9194

95+
if (this.transactionManager != null) {
96+
step.setTransactionManager(this.transactionManager);
97+
}
98+
9299
if (transactionAttribute != null) {
93100
step.setTransactionAttribute(transactionAttribute);
94101
}
@@ -220,6 +227,16 @@ public B stepOperations(RepeatOperations repeatTemplate) {
220227
return self();
221228
}
222229

230+
/**
231+
* Set the transaction manager to use for the step.
232+
* @param transactionManager a transaction manager
233+
* @return this for fluent chaining
234+
*/
235+
public B transactionManager(PlatformTransactionManager transactionManager) {
236+
this.transactionManager = transactionManager;
237+
return self();
238+
}
239+
223240
/**
224241
* Sets the transaction attributes for the tasklet execution. Defaults to the default
225242
* values for the transaction manager, but can be manipulated to provide longer
@@ -275,4 +292,8 @@ protected Set<ItemStream> getStreams() {
275292
return this.streams;
276293
}
277294

295+
protected PlatformTransactionManager getTransactionManager() {
296+
return this.transactionManager;
297+
}
298+
278299
}

spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/SimpleStepBuilder.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import org.springframework.batch.repeat.policy.SimpleCompletionPolicy;
5252
import org.springframework.batch.repeat.support.RepeatTemplate;
5353
import org.springframework.batch.support.ReflectionUtils;
54+
import org.springframework.transaction.PlatformTransactionManager;
5455
import org.springframework.util.Assert;
5556

5657
/**
@@ -108,6 +109,7 @@ protected SimpleStepBuilder(SimpleStepBuilder<I, O> parent) {
108109
this.processor = parent.processor;
109110
this.itemListeners = parent.itemListeners;
110111
this.readerTransactionalQueue = parent.readerTransactionalQueue;
112+
this.transactionManager(parent.getTransactionManager());
111113
}
112114

113115
public FaultTolerantStepBuilder<I, O> faultTolerant() {

spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/StepBuilderHelper.java

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,11 @@
3636

3737
/**
3838
* A base class and utility for other step builders providing access to common properties
39-
* like job repository and transaction manager.
39+
* like job repository and listeners.
4040
*
4141
* @author Dave Syer
4242
* @author Michael Minella
43+
* @author Mahmoud Ben Hassine
4344
* @since 2.2
4445
*/
4546
public abstract class StepBuilderHelper<B extends StepBuilderHelper<B>> {
@@ -67,11 +68,6 @@ public B repository(JobRepository jobRepository) {
6768
return self();
6869
}
6970

70-
public B transactionManager(PlatformTransactionManager transactionManager) {
71-
properties.transactionManager = transactionManager;
72-
return self();
73-
}
74-
7571
public B startLimit(int startLimit) {
7672
properties.startLimit = startLimit;
7773
return self();
@@ -116,10 +112,6 @@ protected JobRepository getJobRepository() {
116112
return properties.jobRepository;
117113
}
118114

119-
protected PlatformTransactionManager getTransactionManager() {
120-
return properties.transactionManager;
121-
}
122-
123115
protected boolean isAllowStartIfComplete() {
124116
return properties.allowStartIfComplete != null ? properties.allowStartIfComplete : false;
125117
}
@@ -145,11 +137,6 @@ protected void enhance(Step target) {
145137

146138
}
147139

148-
if (target instanceof TaskletStep) {
149-
TaskletStep step = (TaskletStep) target;
150-
step.setTransactionManager(properties.transactionManager);
151-
}
152-
153140
}
154141

155142
public static class CommonStepProperties {
@@ -162,8 +149,6 @@ public static class CommonStepProperties {
162149

163150
private JobRepository jobRepository;
164151

165-
private PlatformTransactionManager transactionManager;
166-
167152
public CommonStepProperties() {
168153
}
169154

@@ -172,7 +157,6 @@ public CommonStepProperties(CommonStepProperties properties) {
172157
this.startLimit = properties.startLimit;
173158
this.allowStartIfComplete = properties.allowStartIfComplete;
174159
this.jobRepository = properties.jobRepository;
175-
this.transactionManager = properties.transactionManager;
176160
this.stepExecutionListeners = new ArrayList<>(properties.stepExecutionListeners);
177161
}
178162

@@ -184,14 +168,6 @@ public void setJobRepository(JobRepository jobRepository) {
184168
this.jobRepository = jobRepository;
185169
}
186170

187-
public PlatformTransactionManager getTransactionManager() {
188-
return transactionManager;
189-
}
190-
191-
public void setTransactionManager(PlatformTransactionManager transactionManager) {
192-
this.transactionManager = transactionManager;
193-
}
194-
195171
public String getName() {
196172
return name;
197173
}

spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/JobBuilderConfigurationTests.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.springframework.context.annotation.Configuration;
4242
import org.springframework.context.annotation.Import;
4343
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
44+
import org.springframework.jdbc.support.JdbcTransactionManager;
4445
import org.springframework.lang.Nullable;
4546

4647
/**
@@ -114,6 +115,9 @@ public static class TestConfiguration {
114115
@Autowired
115116
private StepBuilderFactory steps;
116117

118+
@Autowired
119+
private JdbcTransactionManager transactionManager;
120+
117121
@Bean
118122
public Job testJob() throws Exception {
119123
SimpleJobBuilder builder = jobs.get("test").start(step1()).next(step2());
@@ -122,12 +126,12 @@ public Job testJob() throws Exception {
122126

123127
@Bean
124128
protected Step step1() throws Exception {
125-
return steps.get("step1").tasklet(tasklet()).build();
129+
return steps.get("step1").tasklet(tasklet()).transactionManager(this.transactionManager).build();
126130
}
127131

128132
@Bean
129133
protected Step step2() throws Exception {
130-
return steps.get("step2").tasklet(tasklet()).build();
134+
return steps.get("step2").tasklet(tasklet()).transactionManager(this.transactionManager).build();
131135
}
132136

133137
@Bean
@@ -157,6 +161,9 @@ public static class AnotherConfiguration {
157161
@Autowired
158162
private StepBuilderFactory steps;
159163

164+
@Autowired
165+
private JdbcTransactionManager transactionManager;
166+
160167
@Autowired
161168
private Tasklet tasklet;
162169

@@ -168,7 +175,7 @@ public Job anotherJob() throws Exception {
168175

169176
@Bean
170177
protected Step step3() throws Exception {
171-
return steps.get("step3").tasklet(tasklet).build();
178+
return steps.get("step3").tasklet(tasklet).transactionManager(this.transactionManager).build();
172179
}
173180

174181
}
@@ -217,6 +224,9 @@ public static class BeansConfigurer {
217224
@Autowired
218225
private StepBuilderFactory steps;
219226

227+
@Autowired
228+
private JdbcTransactionManager transactionManager;
229+
220230
@Bean
221231
public Job beansConfigurerJob() throws Exception {
222232
SimpleJobBuilder builder = jobs.get("beans").start(step1());
@@ -232,7 +242,7 @@ protected Step step1() throws Exception {
232242
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
233243
return null;
234244
}
235-
}).build();
245+
}).transactionManager(this.transactionManager).build();
236246
}
237247

238248
@Bean
@@ -252,6 +262,11 @@ public DataSource dataSource() {
252262
.addScript("/org/springframework/batch/core/schema-hsqldb.sql").generateUniqueName(true).build();
253263
}
254264

265+
@Bean
266+
public JdbcTransactionManager transactionManager(DataSource dataSource) {
267+
return new JdbcTransactionManager(dataSource);
268+
}
269+
255270
}
256271

257272
}

spring-batch-core/src/test/java/org/springframework/batch/core/configuration/annotation/JobLoaderConfigurationTests.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.springframework.batch.core.scope.context.ChunkContext;
3838
import org.springframework.batch.core.step.tasklet.Tasklet;
3939
import org.springframework.batch.repeat.RepeatStatus;
40+
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
4041
import org.springframework.beans.factory.annotation.Autowired;
4142
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
4243
import org.springframework.context.annotation.Bean;
@@ -135,12 +136,14 @@ public Job testJob() throws Exception {
135136

136137
@Bean
137138
protected Step step1() throws Exception {
138-
return steps.get("step1").tasklet(tasklet()).build();
139+
return steps.get("step1").tasklet(tasklet()).transactionManager(new ResourcelessTransactionManager())
140+
.build();
139141
}
140142

141143
@Bean
142144
protected Step step2() throws Exception {
143-
return steps.get("step2").tasklet(tasklet()).build();
145+
return steps.get("step2").tasklet(tasklet()).transactionManager(new ResourcelessTransactionManager())
146+
.build();
144147
}
145148

146149
@Bean
@@ -179,7 +182,7 @@ protected Step step3() throws Exception {
179182
public RepeatStatus execute(StepContribution contribution, ChunkContext context) throws Exception {
180183
return RepeatStatus.FINISHED;
181184
}
182-
}).build();
185+
}).transactionManager(new ResourcelessTransactionManager()).build();
183186
}
184187

185188
}

spring-batch-core/src/test/java/org/springframework/batch/core/job/builder/FlowJobBuilderTests.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
5656
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
5757
import org.springframework.lang.Nullable;
58+
import org.springframework.transaction.PlatformTransactionManager;
5859

5960
/**
6061
* @author Dave Syer
@@ -289,16 +290,19 @@ static class JobConfiguration {
289290

290291
@Bean
291292
@JobScope
292-
public Step step(StepBuilderFactory stepBuilderFactory,
293+
public Step step(StepBuilderFactory stepBuilderFactory, PlatformTransactionManager transactionManager,
293294
@Value("#{jobParameters['chunkSize']}") Integer chunkSize) {
294295
return stepBuilderFactory.get("step").<Integer, Integer>chunk(chunkSize)
295-
.reader(new ListItemReader<>(Arrays.asList(1, 2, 3, 4))).writer(items -> {
296+
.transactionManager(transactionManager).reader(new ListItemReader<>(Arrays.asList(1, 2, 3, 4)))
297+
.writer(items -> {
296298
}).build();
297299
}
298300

299301
@Bean
300-
public Job job(JobBuilderFactory jobBuilderFactory) {
301-
return jobBuilderFactory.get("job").flow(step(null, null)).build().build();
302+
public Job job(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory,
303+
PlatformTransactionManager transactionManager) {
304+
Step step = step(stepBuilderFactory, transactionManager, null);
305+
return jobBuilderFactory.get("job").flow(step).build().build();
302306
}
303307

304308
@Bean
@@ -307,6 +311,11 @@ public DataSource dataSource() {
307311
.addScript("/org/springframework/batch/core/schema-hsqldb.sql").generateUniqueName(true).build();
308312
}
309313

314+
@Bean
315+
public JdbcTransactionManager transactionManager(DataSource dataSource) {
316+
return new JdbcTransactionManager(dataSource);
317+
}
318+
310319
}
311320

312321
}

0 commit comments

Comments
 (0)