为什么在一个步骤中设置TransactionManager为JPATransactionManager不正确?<



我正在使用Spring Batch和JPA,并且我经历了TransactionManager bean冲突。我通过在一个步骤中将TransactionManager设置为JpaTransactionManager找到了一个解决方案。但根据这个链接(https://github.com/spring-projects/spring-batch/issues/961),这是不正确的,即使它适用于我。

@Autowired
private JpaTransactionManager transactionManager;
private Step buildTaskletStep() {
return stepBuilderFactory.get("SendCampaignStep")
.<UserAccount, UserAccount>chunk(pushServiceConfiguration.getCampaignBatchSize())
.reader(userAccountItemReader)
.processor(userAccountItemProcessor)
.writer(userAccountItemWriter)
.transactionManager(transactionManager)
.build();
}
}

我尝试了实现batchconfigiler的建议解决方案,但它与我使用以下代码禁用元数据表相冲突:

@Configuration
@EnableAutoConfiguration
@EnableBatchProcessing
public class BatchConfiguration extends DefaultBatchConfigurer {
@Override
public void setDataSource(DataSource dataSource) {
// override to do not set datasource even if a datasource exist.
// initialize will use a Map based JobRepository (instead of database)
}
}

使用在步骤中设置TransactionManager的第一种解决方案会有什么问题?

在Spring Batch中,有两个地方使用事务管理器:

  • JobRepository周围创建的代理中,在与作业存储库交互时创建事务方法
  • 在每个步骤定义中驱动步骤的事务

通常,在两个地方使用相同的事务管理器,但这不是必需的。在作业存储库中使用ResourcelessTransactionManager来不存储任何元数据,在步骤中使用JpaTransactionManager来将数据持久化到数据库中,这是完全可以的。

默认情况下,当您使用@EnableBatchProcessing并提供DataSourcebean时,Spring Batch将创建DataSourceTransactionManager并在两个位置设置它,因为这是最典型的情况。但是没有什么可以阻止您为该步骤使用不同的事务管理器。在这种情况下,您应该接受当出现问题时业务数据和技术元数据可能不同步的事实。

这就是为什么提供自定义事务管理器的预期方式是通过自定义BatchConfigurer#getTransactionManager,在这种情况下,您的自定义事务管理器在两个地方都设置了它。这个问题没有明确的文档记录,但自v4.1以来已经修复了。下面是提到这一点的部分:配置jobrerepository。@EnableBatchProcessing:

的Javadoc中也提到了这一点
In order to use a custom transaction manager, a custom BatchConfigurer should be provided.

相关内容

  • 没有找到相关文章

最新更新