JPA 中 flush 的确切目的是什么

What is exact purpose of flush in JPA

一些令人困惑的解释: 冲洗();刷新是将底层持久存储与 memory.it 中保存的持久状态同步的过程,将更新或插入 运行 事务中的表,但它可能不会提交这些更改。

如果更改无论如何都只会在提交后持久保存在数据库中,那么为什么要在代码中间刷新。

并且在 运行 刷新之后,如果对托管对象进行了任何更改,那么将抛出异常,或者将那些同步然后将被保留。如果他们得到同步,那么为什么首先要刷新。

当事务提交时,实体管理器会为您执行刷新操作。在某些情况下,例如在容器管理的事务中处理乐观锁定,您可能需要手动调用 flush 方法来捕获和处理特定的锁定异常。

理论上,您(作为 JPA 的用户)永远不应该(或在极少数情况下)遇到调用 flush().

的情况

Flushing is the process of synchronizing the underlying persistent store with persistable state held in memory

换句话说,在 flush() 上,所有插入、更新、删除或任何实际上在数据库上调用的语句,在 flush() 之前,您的数据库没有任何反应。刷新是由您的事务提交或某些类型的数据库读取引起的。例如,如果您执行 JPQL 查询,则必须执行 flush() 才能从数据库中获取正确的结果。但是,知道这一点非常好,并且由您的 JPA 实现完全处理。

在某些情况下,您可能希望自己控制此刷新,然后您可以使用 flush() 调用它。

编辑回答评论中的问题:

并非每次读取都需要刷新,考虑这种情况(一个事务):

  1. 读一个人Person p = em.find(Person.class, 234)
  2. 更新人物p.setAge(31)
  3. 读一栋楼Building b = em.find(Building.class, 123
  4. 使用 JPQL 查询读取建筑物 select b from Building b where b.id = 123

Automatic flush 只发生在 4. 之前,因为 Eclipselink 不能确定你要读什么,所以这个人的年龄必须在读之前在数据库上是最新的可能发生。 3.之前不需要刷新,因为Eclipselink知道更新一个人不会影响一个建筑。

要使用乐观锁定,您必须实现它。在此处阅读有关 @Version 注释的信息:https://blogs.oracle.com/carolmcdonald/entry/jpa_2_0_concurrency_and。否则您的实体将不会使用乐观锁定和 "last update wins".