[JAVA] Use different TransactionManager for metadata and step in spring-batch

When using two or more data sources in spring-batch, specify transaction manager with `StepBuilderHelper # transactionManager` when creating step definition.

The following is a setting example.

import java.util.stream.Collectors;
import java.util.stream.IntStream;

import javax.sql.DataSource;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.step.tasklet.TaskletStep;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.batch.BatchDataSource;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

@SpringBootApplication
@EnableBatchProcessing
public class Application {
	@Bean
	@BatchDataSource
	public DataSource springBatchDs() {
		// 1
		return DataSourceBuilder
				.create()
				.url("jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE")
				.username("sa")
				.password("")
				.build();
	}
	
	@Bean
	@Primary
	public DataSource primaryDs() {
		// 2
		return DataSourceBuilder
				.create()
				.url("jdbc:oracle:thin:system/oracle@localhost:11521/XEPDB1")
				.username("system")
				.password("oracle")
				.build();
	}
	
	
	@Bean
	public Job job(JobBuilderFactory jobs, Step s1) {
		return jobs.get("myJob")
				.incrementer(new RunIdIncrementer())
				.start(s1)
				.build();
	}
	
	@Bean("stepTransactionManager")
	public PlatformTransactionManager stepTransactionManager(DataSource primaryDs) {
		// 3
		return new DataSourceTransactionManager(primaryDs);
	}
	
	@Bean
	public Step step1(StepBuilderFactory steps
			,DataSource dataSource
			// 4
			,@Qualifier("stepTransactionManager") PlatformTransactionManager transactionManager) {
		ItemReader<Integer> reader = new ListItemReader<Integer>(
				IntStream.range(1, 1001).boxed().collect(Collectors.toList()));

		JdbcTemplate jdbc = new JdbcTemplate(dataSource);
		
		TaskletStep build = steps.get("step1")
				// 5
				.transactionManager(transactionManager)
				.<Integer, Integer>chunk(10)
				.reader(reader)
				.writer(list -> {
					list.forEach(s -> {
						jdbc.update("update aaa set user_id = user_id + 1");
					});
				})
				.build();
		return build;
	}
	
	public static void main(String[] args) {
		new SpringApplicationBuilder(Application.class).web(WebApplicationType.NONE).run(args);
	}
}
  1. As a sample, use H2 as the storage destination for metadata. The metadata is virtually non-persistent as it disappears at the end.
  2. Main data source.
  3. Transaction manager for step processing. Use the main data source. Since the main data source has `` `@ Primary```, that data source comes as an argument of this method.
  4. Get the transaction manager created above with `@ Qualifier```. Without @ Qualifier```, ``` transactionManager``` created internally by `` SimpleBatchConfiguration``` of spring-batch will be included.
  5. step Specify the transaction manager created above when creating the definition. This uses different transaction managers for metadata processing and step processing.

Recommended Posts

Use different TransactionManager for metadata and step in spring-batch
Use variables for class and id names in haml
Use docker-compose.yml which is different for each environment in Makefile
How to use \ t Escape sequences different for mac and Windows-java
Getter names are different in lombok and eclipse for fields like `rPoint`
[Java] for Each and sorted in Lambda
Display SF Symbols in different sizes and colors
Criteria for proper use of render and redirect_to
Use pagy for pagination in your Rails app.
Use Shift Right and Shift Left properly in Selenium