JpaItemWriter:没有正在进行的交易 [英] JpaItemWriter: no transaction is in progress
问题描述
我想使用 JpaItemWriter 来批量持久化实体.但是当我使用以下代码坚持时,我被告知:
I'd like to use JpaItemWriter to batch persist entities. But when I use the following code to persist, I'm told:
Hibernate:
select
nextval ('hibernate_sequence')
[] 2014-03-19 15:46:02,237 ERROR : TransactionRequiredException: no transaction is in progress
如何启用以下交易:
@Bean
public ItemWriter<T> writer() {
JpaItemWriter<T> itemWriter = new JpaItemWriter<>();
itemWriter.setEntityManagerFactory(emf);
}
@Configuration
@EnableTransactionManagement
@EnableBatchProcessing
class Config{ {
@Bean
public LocalContainerEntityManagerFactoryBean emf() {
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(dataSource());
emf.setPackagesToScan("my.package");
emf.setJpaVendorAdapter(jpaAdapter());
emf.setJpaProperties(jpaProterties());
return emf;
}
@Bean
public Job airlineJob(JobBuilderFactory jobs, Step step) {
return jobs.get("job")
.start(step)
.build();
}
//Reader is a `FlatFileItemReader`, writer is `CustomItemWriter`.
@Bean
public Step step(StepBuilderFactory steps,
MultiResourceItemReader<T> rea,
ItemProcessor<T, T> pro,
ItemWriter<T> wr) {
return steps.get("step")
.reader(rea)
.processor(proc)
.writer(wr)
.build();
}
//use same datasource and tx manager as in the full web application
@Bean
public JobLauncher launcher(TransactionManager tx, DataSource ds) throws Exception {
SimpleJobLauncher launcher = new SimpleJobLauncher();
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(ds);
factory.setTransactionManager(tx);
jobLauncher.setJobRepository(factory.getJobRepository());
return launcher;
}
<小时>
编辑 2 作为对@Haim 的回应:
Edit 2 as response to @Haim:
@Bean
public JpaItemWriter<T> jpaItemWriter(EntityManagerFactory emf) {
JpaItemWriter<T> writer = new JpaItemWriter<T>();
writer.setEntityManagerFactory(emf);
return writer;
}
推荐答案
我同意 Michael Minella 的观点:Spring 批处理作业存储库不喜欢与他人共享其事务管理器.逻辑很简单,如果您在步骤失败时与步骤事务管理器共享您的作业事务管理器,它将回滚步骤和写入作业存储库的数据.这意味着您不会为作业重新启动保留数据.为了使用两个事务管理器,您需要:
I agree with Michael Minella: Spring batch job repository does not like to share its transaction manager with others. The logic is simple, if you share your job transaction manager with your step transaction manager upon step failure it will rollback both the step and the data written to the job repository. This means that you will not persist data for job restart. In order to use two transaction managers you need to:
删除@EnableTransactionManagement,以防您仅将其用于上面的@Transactional
定义额外的事务管理器
Delete @EnableTransactionManagement in case you use it only for the @Transactional above
Define an additional transaction manager
@Bean
@Qualifier("jpaTrx")
public PlatformTransactionManager jpaTransactionManager() {
return new JpaTransactionManager(emf());
}
将事务管理器设置为您的步骤
Set the transaction manager to your step
@Autowired
@Qualifier("jpaTrx")
PlatformTransactionManager jpaTransactionManager
//Reader is a FlatFileItemReader, writer is CustomItemWriter.
@Bean
public Step step(StepBuilderFactory steps,
MultiResourceItemReader<T> rea,
ItemProcessor<T, T> pro,
ItemWriter<T> wr) {
return steps.get("step")
//attach tx manager
.transactionManager(jpaTransactionManager)
.reader(rea)
.processor(proc)
.writer(wr)
.build();
}
这篇关于JpaItemWriter:没有正在进行的交易的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!