当前位置: 首页 > 面试题库 >

使用Spring Batch进行交易管理

濮阳和泰
2023-03-14
问题内容

我实际上发现了Spring,并且能够设置一些作业。现在,我想使用Hibernate / JPA将导入的数据保存在数据库中,并且不断出现此错误:

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

我看到问题出在交易上。这是我的entityManager和的春季java配置transactionManager

 @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<EntiteJuridiqueJPA> writer()
  {
    JpaItemWriter<EntiteJuridiqueJPA> writer = new JpaItemWriter<EntiteJuridiqueJPA>();    
    writer.setEntityManagerFactory(entityManagerFactory.getObject());
    return writer;
  }

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

有什么想法可以解决这个问题吗?

[编辑]我还要输入Job定义和step定义。我所有的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").<EntiteJuridique, EntiteJuridiqueJPA> chunk(5).reader(cvsReader(null))
        .processor(processor()).writer(writer()).listener(processListener()).build();
  }

  @Bean
  @StepScope
  public FlatFileItemReader<EntiteJuridique> cvsReader(@Value("#{jobParameters[input]}") String input)
  {
    FlatFileItemReader<EntiteJuridique> flatFileReader = new FlatFileItemReader<EntiteJuridique>();
    flatFileReader.setLineMapper(lineMapper());
    flatFileReader.setResource(new ClassPathResource(input));
    return flatFileReader;
  }

  @Bean
  public LineMapper<EntiteJuridique> lineMapper()
  {
    DefaultLineMapper<EntiteJuridique> lineMapper = new DefaultLineMapper<EntiteJuridique>();
    DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();
    lineTokenizer.setDelimiter(";");
    lineTokenizer.setNames(new String[] { "MEGA_ENTITE", "PORTEFEUILLE", "MEGA_ENTITE", "Libellé" });

    BeanWrapperFieldSetMapper<EntiteJuridique> fieldSetMapper = new BeanWrapperFieldSetMapper<EntiteJuridique>();
    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<EntiteJuridique, EntiteJuridiqueJPA> processor()
  {
    return new EntiteJuridiqueProcessor();
  }

  @Bean
  public ItemWriter<EntiteJuridiqueJPA> writer()
  {
    JpaItemWriter<EntiteJuridiqueJPA> writer = new JpaItemWriter<EntiteJuridiqueJPA>();    
    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的建议,但是仍然遇到相同的异常。我已经独立于spring-
batch测试了我的entityManager,并且能够将任何数据存储在数据库中。

但是,当在Spring Batch中使用相同的实体管理器时,会出现此异常。

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


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


 类似资料:
  • 交易管理器 web3j提供了一个交易管理器TransactionManager来控制你连接到以太坊客户端的方式。默认机制使用web3j的RawTransactionManager,它与以太坊钱包文件一起工作,在提交到网络之前离线地签署交易。 但是,你可能希望修改交易管理,也可以将其传递给智能合约部署和构建方法deploy,而不是凭据对象,即: YourSmartContract contract

  • 问题内容: 我需要一个示例来使用GoLang在MongoDB中实现事务。 我正在使用此golang驱动程序用于mongodb https://github.com/mongodb/mongo-go-driver 没有有关如何实现事务的清晰文档。 谁能帮我? 问题答案: 可能会造成混乱。以下是一个简单的示例。 您可以在此处查看完整的示例。

  • 问题内容: 我正在开发基于JPA +Hibernate,Spring和Wicket的Web应用程序。我想知道在我的代码中实现事务的最佳方法是什么?我应该使用什么交易经理?应该是,还是其他?我想用Spring来管理我的交易。 问题答案: 南大是正确的,你 可以 只使用JpaTransactionManager接口。我们在这里谈论的事务管理器抽象是Spring的PlatformTransactionM

  • 本文向大家介绍在保护交易记录时,您将如何进行风险管理?相关面试题,主要包含被问及在保护交易记录时,您将如何进行风险管理?时的应答技巧和注意事项,需要的朋友参考一下 回答:** 基于数据的价值,可以采用多种方法来处理风险管理。 首先,确定与组织的财务记录相关的威胁和漏洞,并相应地采取正确的对策。 另一种方法是注意备份计划。 第三是购买新的风险管理软件。

  • 问题内容: 通常,播放!在请求成功完成后提交事务。在Play中手动提交交易的正确方法是什么? 问题答案: 您可以通过调用JPA.em()获得Hibernate EntityManager。然后,您可以从那里访问事务(JPA.em()。getTransaction())。 如果您打算自己管理事务,则将要禁用Play!的事务处理(可以在方法或控制器上使用@NoTransaction注释来执行此操作)。

  • 问题内容: 我想使用SpringContextTests测试我的Dao类。 在我的方法类中,我扩展了,以便我的测试类与JUnit4集成。我还设置了配置,并在和的DownDown中进行了初始化和数据库清理。我的测试课效果很好。 我的问题是,当我运行测试类并且数据库中充满了数据时,原始数据没有回滚并且数据库被清除了。在该方法中,我清除数据库并填充数据,以为我可以回滚数据库,但不能回滚。 任何人都可以找