【问题标题】:Spring Boot - Persist transaction directly to embedded databaseSpring Boot - 将事务直接持久化到嵌入式数据库
【发布时间】:2017-01-09 10:27:21
【问题描述】:

我在带有嵌入式 H2 数据库的独立 GUI (Swing) java 应用程序中使用 Spring Boot Jpa。

我使用 Spring Boot 1.3.0,这是我的附加配置:

  private static final String dataSourceUrl = "jdbc:h2:./databse;DB_CLOSE_ON_EXIT=FALSE";
  @Bean
  public DataSource dataSource() {
      return DataSourceBuilder.create().url(dataSourceUrl).username("user").password("pwd").build();
  }

  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
      LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
      em.setDataSource(dataSource);
      em.setPackagesToScan(new String[] { "packages.to.scan" });

      JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
      em.setJpaVendorAdapter(vendorAdapter);

      Properties properties = new Properties();
      properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
      properties.setProperty("hibernate.hbm2ddl.auto", "update");
      em.setJpaProperties(properties);

      return em;
  }

在我的application.properties 文件中,我只有一行:spring.aop.proxy-target-class=true

对于我的存储库,我扩展了JpaRepository

一切正常,我最近遇到的唯一问题:在运行应用程序的 MAC 上,MAC 出现了某种问题并崩溃了。之后,之前所做的任何修改都没有实际存储在数据库中。我使用@Transactional注解修改数据库中的数据。

我对数据库不是很有经验,但是在谷歌搜索之后,我猜事务是由持久性上下文缓存的(不确定术语是否正确),并且在应用程序关闭时实际上是持久化的。我检查了数据库文件并通过 GUI 进行了一些操作(还包括一些查询),但数据库文件的修改日期仅在我关闭应用程序时才更改。

由于这是一个独立的 GUI 应用程序,因此如果每个事务都直接保存在数据库中,则不会出现性能问题。我是否走在正确的道路上,如何实现每个事务都直接保存在数据库中?每次调用存储库的save() 方法后,我是否需要进行任何配置或添加任何代码?

如果不是,我完全不知道如何调试这类问题,因为我不得不承认我不太确定引擎盖下到底发生了什么..

【问题讨论】:

  • 事务提交并刷新后,更改将保存到数据库中。后者通常在事务完成后的短时间内发生,而不是在您停止应用程序时发生。你有没有检查过,你的交易绑定不是太大?如果您只对整个应用程序使用一个事务,那么它可能只有在您停止应用程序时才会被提交。
  • 至少我不会故意在整个应用程序中使用一个事务。我添加了一些函数propagation = Propagation.REQUIRES_NEW并在调用此函数的 GUI 中执行了一些操作,但结果是相同的:只有在我关闭应用程序时才会修改数据库文件。

标签: java spring hibernate spring-boot spring-data-jpa


【解决方案1】:

Hibernate 根据优化参数和配置的刷新策略自行决定何时写入数据库(刷新持久性上下文)。

也许你可以看看这里并根据你的需要调整行为:

https://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch03.html

有关刷新模式的信息也会对您有所帮助:

http://docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/FlushMode.html

【讨论】:

    【解决方案2】:

    Springs @Transactional 遵循容器管理的事务范式。默认情况下,如果一个 @Transactional 在另一个 Componet/service/repository 中调用 @Transactional 方法,则会传播事务。当最外层的@Transactional 方法完成时,事务将提交到数据库。

    JPA 可以在同一个事务中多次将数据刷新到数据库,但事务中的所有内容在事务完成时要么提交要么回滚。如果您在@Controller 上有@Transactional,则事务在 DispatchServlet 调用处理程序方法后完成(更具体地说,它发生在使用 Spring AOP 创建的 GCLIB 或 JDK 代理内部)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-09
      • 2021-07-09
      • 2018-02-26
      • 1970-01-01
      • 1970-01-01
      • 2020-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多