Skip to content

Commit bb87faf

Browse files
BenchmarkingBuffaloscottfrederick
authored andcommitted
Add BatchTransactionManager annotation
Add a new @BatchTransactionManager annotation for marking a PlatformTransactionManager that should be used in batch processing. See gh-39473
1 parent 51991d6 commit bb87faf

File tree

4 files changed

+93
-2
lines changed

4 files changed

+93
-2
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
* @author Kazuki Shimizu
6666
* @author Mahmoud Ben Hassine
6767
* @author Lars Uffmann
68+
* @author Lasse Wulff
6869
* @since 1.0.0
6970
*/
7071
@AutoConfiguration(after = { HibernateJpaAutoConfiguration.class, TransactionAutoConfiguration.class })
@@ -108,11 +109,13 @@ static class SpringBootBatchConfiguration extends DefaultBatchConfiguration {
108109
private final ExecutionContextSerializer executionContextSerializer;
109110

110111
SpringBootBatchConfiguration(DataSource dataSource, @BatchDataSource ObjectProvider<DataSource> batchDataSource,
111-
PlatformTransactionManager transactionManager, BatchProperties properties,
112+
PlatformTransactionManager transactionManager,
113+
@BatchTransactionManager ObjectProvider<PlatformTransactionManager> batchTransactionManager,
114+
BatchProperties properties,
112115
ObjectProvider<BatchConversionServiceCustomizer> batchConversionServiceCustomizers,
113116
ObjectProvider<ExecutionContextSerializer> executionContextSerializer) {
114117
this.dataSource = batchDataSource.getIfAvailable(() -> dataSource);
115-
this.transactionManager = transactionManager;
118+
this.transactionManager = batchTransactionManager.getIfAvailable(() -> transactionManager);
116119
this.properties = properties;
117120
this.batchConversionServiceCustomizers = batchConversionServiceCustomizers.orderedStream().toList();
118121
this.executionContextSerializer = executionContextSerializer
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright 2012-2014 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.batch;
18+
19+
import java.lang.annotation.Documented;
20+
import java.lang.annotation.ElementType;
21+
import java.lang.annotation.Retention;
22+
import java.lang.annotation.RetentionPolicy;
23+
import java.lang.annotation.Target;
24+
25+
import org.springframework.beans.factory.annotation.Qualifier;
26+
import org.springframework.context.annotation.Primary;
27+
import org.springframework.transaction.PlatformTransactionManager;
28+
29+
/**
30+
* Qualifier annotation for a {@link PlatformTransactionManager
31+
* PlatformTransactionManager} to be injected into Batch auto-configuration. Can be used
32+
* on a secondary {@link PlatformTransactionManager PlatformTransactionManager}, if there
33+
* is another one marked as {@link Primary @Primary}.
34+
*
35+
* @author Lasse Wulff
36+
* @since 3.3.0
37+
*/
38+
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE })
39+
@Retention(RetentionPolicy.RUNTIME)
40+
@Documented
41+
@Qualifier
42+
public @interface BatchTransactionManager {
43+
44+
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java

+36
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
import org.springframework.context.annotation.Primary;
8181
import org.springframework.core.annotation.Order;
8282
import org.springframework.core.convert.support.ConfigurableConversionService;
83+
import org.springframework.integration.transaction.PseudoTransactionManager;
8384
import org.springframework.jdbc.BadSqlGrammarException;
8485
import org.springframework.jdbc.core.JdbcTemplate;
8586
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
@@ -102,6 +103,7 @@
102103
* @author Kazuki Shimizu
103104
* @author Mahmoud Ben Hassine
104105
* @author Lars Uffmann
106+
* @author Lasse Wulff
105107
*/
106108
@ExtendWith(OutputCaptureExtension.class)
107109
class BatchAutoConfigurationTests {
@@ -351,6 +353,18 @@ void testBatchDataSource() {
351353
});
352354
}
353355

356+
@Test
357+
void testBatchTransactionManager() {
358+
this.contextRunner.withUserConfiguration(TestConfiguration.class, BatchTransactionManagerConfiguration.class)
359+
.run((context) -> {
360+
assertThat(context).hasSingleBean(SpringBootBatchConfiguration.class);
361+
PlatformTransactionManager batchTransactionManager = context.getBean("batchTransactionManager",
362+
PlatformTransactionManager.class);
363+
assertThat(context.getBean(SpringBootBatchConfiguration.class).getTransactionManager())
364+
.isEqualTo(batchTransactionManager);
365+
});
366+
}
367+
354368
@Test
355369
void jobRepositoryBeansDependOnBatchDataSourceInitializer() {
356370
this.contextRunner.withUserConfiguration(TestConfiguration.class, EmbeddedDataSourceConfiguration.class)
@@ -519,6 +533,28 @@ public DataSource batchDataSource() {
519533

520534
}
521535

536+
@Configuration(proxyBeanMethods = false)
537+
protected static class BatchTransactionManagerConfiguration {
538+
539+
@Bean
540+
public DataSource dataSource() {
541+
return DataSourceBuilder.create().url("jdbc:hsqldb:mem:database").username("sa").build();
542+
}
543+
544+
@Bean
545+
@Primary
546+
public PlatformTransactionManager normalTransactionManager() {
547+
return new PseudoTransactionManager();
548+
}
549+
550+
@BatchTransactionManager
551+
@Bean
552+
public PlatformTransactionManager batchTransactionManager() {
553+
return new PseudoTransactionManager();
554+
}
555+
556+
}
557+
522558
@Configuration(proxyBeanMethods = false)
523559
static class EmptyConfiguration {
524560

spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/batch.adoc

+8
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ For more info about Spring Batch, see the {spring-batch}[Spring Batch project pa
1919

2020

2121

22+
[[howto.batch.specifying-a-transaction-manager]]
23+
=== Specifying a Batch Transaction Manager
24+
Similar to <<howto.batch.specifying-a-data-source>> you can also define a `PlatformTransactionManager`
25+
for use in the batch processing by marking it as `@BatchTransactionManager`.
26+
If you do so and want two transaction managers, remember to mark the other one as `@Primary`.
27+
28+
29+
2230
[[howto.batch.running-jobs-on-startup]]
2331
=== Running Spring Batch Jobs on Startup
2432
Spring Batch auto-configuration is enabled by adding `spring-boot-starter-batch` to your application's classpath.

0 commit comments

Comments
 (0)