JpaItemWriter:没有事务在进行中 [英] JpaItemWriter: no transaction is in progress

查看:108
本文介绍了JpaItemWriter:没有事务在进行中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆