【问题标题】:Calling flush() in @Transactional method in Spring Boot application在 Spring Boot 应用程序的 @Transactional 方法中调用 flush()
【发布时间】:2019-06-12 22:51:06
【问题描述】:

在@Transactional方法中间调用Hibernate flush()是否有可能将不完整的结果保存在数据库中? 例如,这个函数是否可以将“John”保存到数据库中?

@Transactional
public void tt() {
    Student s = new Student("John");
    em.persist(s);
    em.flush();
    // Perform some calculations that change some attributes of the instance
    s.setName("Jeff");
}

我在 H2 内存数据库中尝试过,它没有保存不完整的事务更改。但是在某些条件下是否可能,并且可能与另一个数据库引擎一起使用?

【问题讨论】:

  • 为什么会保存不完整的更改?这就是为什么交易就是交易。事务可以完成或未完成,但不能部分完成。如果你想实现一个行为,你应该使用 2 个单独的事务。
  • aBnormaLz,我就是这么想的。但是在有关 Hibernate 和 Spring 的视频之一中,据说 flush() 会强制实体管理器保存这些更改,并且如果在调用 flush() 后此方法中出现问题,这些更改将被回滚。

标签: java sql spring hibernate jpa


【解决方案1】:

在您调用em.commit() 或事务结束之前,它不应保存任何内容。我找到的最佳解释来自 here 。下面是基本摘录:

此操作将导致 DML 语句(插入/更新/删除等)执行到数据库,但不会提交当前事务。这意味着 flush() 不会使当前更改对其他 EntityManager 实例或其他外部数据库客户端可见;这只会在事务提交时发生。换句话说,flush() 操作只会将当前内存缓存从 EntityManager 刷新到数据库会话中。

因此,刷新可能会引发一些 JPA 异常,但它实际上不会在事务结束之前提交到数据库。

相关问题:JPA flush vs commit

【讨论】:

  • 谢谢,这就是我要找的。​​span>
  • @pirho 但是,如果您正在处理大笔交易并且需要在某处显示“状态”怎么办?
  • @user2992476 不确定我是否理解您的意思,但您是否可以拆分数据以一次插入/更新 1000 行并在两者之间调用 flush()?我不确定你的问题与 flush() 有什么关系,但也许你想问一个新的问题?
猜你喜欢
  • 2019-03-08
  • 2017-08-25
  • 1970-01-01
  • 1970-01-01
  • 2017-07-11
  • 1970-01-01
  • 2013-10-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多