【发布时间】:2022-12-04 15:08:43
【问题描述】:
我们使用带有 2 个数据源的 Spring Batch:1 个用于读取(源数据库),1 个用于写入(目标数据库)。
Spring Batch 配置为使用 JobRepository 和 JobExplorer 的目标数据源/事务管理器:
@EnableBatchProcessing(transactionManagerRef = "destinationTransactionManager", dataSourceRef = "destinationDataSource")
对于作业配置,JpaCursorItemReader被配置为使用属于源数据库的EntityManagerFactory(带有属于源数据库的PlatformTransactionManager)。
JpaItemWriter 配置为使用属于目标数据库的EntityManagerFactory 和PlatformTransactionManager。这个 PlatformTransactionManager 与 @EnableBatchProcessing 中使用的是同一个。
我们面向块的步骤使用属于目标数据库的 PlatformTransactionManager(与 @EnableBatchProcessing 中使用的相同)。
我的问题是:这是一个正确的设置吗(尤其是关于事务管理)?到目前为止,它没有给我们带来任何问题。我有点担心,因为读者端使用不同的数据源。
我的假设是这应该有效,因为块的 PlatformTransactionManager 与用于 JobRepository 和 JpaItemWriter 的相同。所以我假设当出现故障时,回滚进度(在元数据表中)和写入的项目至少应该有效,因为它们使用相同的数据源和事务管理器。此外,JpaCursorItemReader 似乎没有事务意识。
我们的配置如下所示(稍作修改以省略领域语言):
@Configuration
@AllArgsConstructor
@EnableBatchProcessing(transactionManagerRef = "destinationTransactionManager", dataSourceRef = "destinationDataSource")
public class JobConfiguration {
@Bean
public JpaCursorItemReader<SourceEntity> sourceReader(
@Qualifier("sourceEntityManagerFactory") final LocalContainerEntityManagerFactoryBean sourceEntityManagerFactory
) {
return new JpaCursorItemReaderBuilder<SourceEntity>()
.name("SourceEntity")
.entityManagerFactory(Objects.requireNonNull(sourceEntityManagerFactory.getObject()))
.queryString("from SourceEntity")
.build();
}
@Bean
public JpaItemWriter<DestinationEntity> destinationWriter(
@Qualifier("destinationEntityManagerFactory")
final LocalContainerEntityManagerFactoryBean destinationEntityManagerFactory
) {
return new JpaItemWriterBuilder<DestinationEntity>()
.entityManagerFactory(Objects.requireNonNull(destinationEntityManagerFactory.getObject()))
.build();
}
@Bean
public Step step(
@Qualifier("sourceReader") final JpaCursorItemReader<SourceEntity> reader,
@Qualifier("destinationWriter") final JpaItemWriter<DestinationEntity> writer,
final CustomProcessor processor, // implementation omitted for brevity
@Qualifier("destinationTransactionManager") final PlatformTransactionManager transactionManager,
final JobRepository jobRepository
) {
return new StepBuilder("step", jobRepository)
.<SourceEntity, DestinationEntity>chunk(10, transactionManager)
.reader(reader)
.processor(processor)
.writer(writer)
.build();
}
@Bean
public Job job(final Step step,
final JobRepository jobRepository) {
return new JobBuilder("job", jobRepository)
.incrementer(new RunIdIncrementer())
.flow(step)
.end()
.build();
}
}
这按预期工作,但我想知道这是否是关于 tx 管理的正确设置。
【问题讨论】:
标签: java spring-boot spring-batch