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);
}
}
`@ Qualifier```. Without
@ Qualifier```, ``` transactionManager``` created internally by ``
SimpleBatchConfiguration``` of spring-batch will be included.Recommended Posts