使用Spring Batch进行事务管理

我发现实际上是Spring,我可以设置一些工作。 现在,我想使用Hibernate / JPA将我导入的数据保存在数据库中,并且我不断收到此错误:

14:46:43.500 [main] ERROR osbcore.step.AbstractStep - Encountered an error executing the step javax.persistence.TransactionRequiredException: no transaction is in progress 

我看到问题出在交易上。 这是我对entityManagertransactionManager spring java配置:

  @Configuration public class PersistenceSpringConfig implements EnvironmentAware { @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws Exception { // Initializes the entity manager LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean(); factoryBean.setPersistenceUnitName(PERSISTENCE_UNIT_NAME); factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); factoryBean.setDataSource(dataSource()); // Scans the database model factoryBean.setPackagesToScan(EntiteJuridiqueJPA.class.getPackage().getName()); // Defines the Hibernate properties Properties jpaProperties = new Properties(); jpaProperties.setProperty("hibernate.show_sql", "false"); jpaProperties.setProperty("hibernate.format_sql", "false"); String connectionURL = "jdbc:h2:file:" + getDatabaseLocation(); jpaProperties.setProperty("hibernate.connection.url", connectionURL); jpaProperties.setProperty("hibernate.connection.username", "sa"); jpaProperties.setProperty("hibernate.connection.driver_class", "org.h2.Driver"); jpaProperties.setProperty("hibernate.dialect", H2Dialect.class.getName()); jpaProperties.setProperty("hibernate.hbm2ddl.auto", "create"); jpaProperties.setProperty("hibernate.hbm2ddl.import_files_sql_extractor", "org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor"); jpaProperties.setProperty("hibernate.hbm2ddl.import_files", "org/springframework/batch/core/schema-drop-h2.sql,org/springframework/batch/core/schema-h2.sql"); factoryBean.setJpaProperties(jpaProperties); return factoryBean; } @Bean public PlatformTransactionManager transactionManager2() throws Exception { EntityManagerFactory object = entityManagerFactory().getObject(); JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(object); return jpaTransactionManager; } 

我正在使用JpaItemWriter将数据存储在数据库中:

  @Bean public ItemWriter writer() { JpaItemWriter writer = new JpaItemWriter(); writer.setEntityManagerFactory(entityManagerFactory.getObject()); return writer; } 

这是导致exception的代码: javax.persistence.TransactionRequiredException: no transaction is in progress

有什么想法如何解决这个问题?

[编辑]我还提出了Job定义和步骤定义。 我的所有Spring配置都是用Java编写的。

  @Configuration @EnableBatchProcessing @Import(PersistenceSpringConfig.class) public class BatchSpringConfig { @Autowired private JobBuilderFactory jobBuilders; @Autowired private StepBuilderFactory stepBuilders; @Autowired private DataSource dataSource; @Autowired private LocalContainerEntityManagerFactoryBean entityManagerFactory; @Bean public Step step() { return stepBuilders.get("step"). chunk(5).reader(cvsReader(null)) .processor(processor()).writer(writer()).listener(processListener()).build(); } @Bean @StepScope public FlatFileItemReader cvsReader(@Value("#{jobParameters[input]}") String input) { FlatFileItemReader flatFileReader = new FlatFileItemReader(); flatFileReader.setLineMapper(lineMapper()); flatFileReader.setResource(new ClassPathResource(input)); return flatFileReader; } @Bean public LineMapper lineMapper() { DefaultLineMapper lineMapper = new DefaultLineMapper(); DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer(); lineTokenizer.setDelimiter(";"); lineTokenizer.setNames(new String[] { "MEGA_ENTITE", "PORTEFEUILLE", "MEGA_ENTITE", "Libellé" }); BeanWrapperFieldSetMapper fieldSetMapper = new BeanWrapperFieldSetMapper(); fieldSetMapper.setTargetType(EntiteJuridique.class); lineMapper.setLineTokenizer(lineTokenizer); lineMapper.setFieldSetMapper(fieldSetMapper); return lineMapper; } @Bean public Job dataInitializer() { return jobBuilders.get("dataInitializer").listener(protocolListener()).start(step()).build(); } @Bean public ItemProcessor processor() { return new EntiteJuridiqueProcessor(); } @Bean public ItemWriter writer() { JpaItemWriter writer = new JpaItemWriter(); writer.setEntityManagerFactory(entityManagerFactory.getObject()); return writer; // return new EntiteJuridiqueWriter(); } @Bean public ProtocolListener protocolListener() { return new ProtocolListener(); } @Bean public CSVProcessListener processListener() { return new CSVProcessListener(); } @Bean public PlatformTransactionManager transactionManager2() throws Exception { EntityManagerFactory object = entityManagerFactory.getObject(); JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(object); return jpaTransactionManager; } 

[编辑]我仍然坚持这个问题。 我通过为stepBuilders设置事务管理器来遵循@Sean Patrick Floyd和@bellabax的建议,但我仍然得到相同的exception。 我已经测试了我的entityManager独立于spring-batch,我能够在数据库中存储任何数据。

但是,当使用弹簧批的相同实体管理器时,我有这个例外。

任何人都可以提供更多见解如何在春季批次管理交易? 谢谢你的帮助?

问题是您正在创建第二个事务管理器(transactionManager2),但Spring Batch正在使用另一个事务管理器来启动事务。 如果使用@EnableBatchProcessing,Spring Batch会自动注册一个事务管理器用于其事务,并且您的JpaTransactionManager永远不会被使用。 如果要更改Spring Batch用于事务的事务管理器,则必须实现BatchConfigurer接口。 看一下这个例子: https : //github.com/codecentric/spring-batch-javaconfig/blob/master/src/main/java/de/codecentric/batch/configuration/WebsphereInfrastructureConfiguration.java 。 在这里,我将事务管理器切换到WebspherUowTransactionManager,并以同样的方式将事务管理器切换到其他事务管理器。 以下是解释它的博客文章的链接: http : //blog.codecentric.de/en/2013/06/spring-batch-2-2-javaconfig-part-3-profiles-and-environments/

您需要在步骤定义中明确引用您的事务管理器:

        

见: 5.1.1。 配置步骤


啊,看到你使用JavaConfig,你需要使用builder.transactionManager(transactionManager)将事务管理器分配给TaskletStepBuilder (inheritance自StepBuilderHelper