【发布时间】:2018-01-05 14:16:07
【问题描述】:
我已经浏览了许多关于 entityManager.flush() 方法的主题。 在我的实践中,我一直使用 persist() 和 commit() 方法。
我还发现,有时 flush() 在 select 对数据库的请求期间会自动执行,此时它会检查数据库的示例约束,因此如果持久对象是错误的由于 select 期间的限制,将引发异常。
其实我也想明白:
当您执行 flush() 方法时,持久化数据是否会保存在数据库中?所以flush()之后就不需要commit()了吗?
使用flush() 代替commit() 有什么好处,可能在一些具体情况下?
【问题讨论】:
-
persist() 只是告诉实体管理器:这必须在事务结束之前保存一段时间。 flush() 执行将内存中的更改复制到数据库所需的插入/更新/删除语句。 Commit 提交事务,使所有这些更改永久化,并且对其他事务可见。 flush() 只是执行 SQL 语句。就像使用 JDBC 一样。
-
您不会执行任何语句,因为 JPA 会为您执行它们。当您通过 em.get() 加载实体时,它会为您执行一条 SQL 语句,从数据库中加载数据,对吗?这将返回一个托管实体(假设是一个用户)。现在如果你做
user.setName("Kirill"),那么你修改内存中的对象,但是JPA也必须修改数据库中的相应行,对吧?这就是 JPA 的全部意义所在。 -
它不能在每次调用 setter 时执行更新语句:这会导致糟糕的性能。所以它会记住记忆中的变化。 flush() 告诉 JPA 在数据库中执行必要的更改。使用插入/更新/删除语句将内存中的所有更改写入数据库。但在事务提交之前,这些更改仍然可以回滚。
-
您几乎不必显式地刷新()。默认情况下,JPA 在提交之前为您刷新。无论您使用什么 API 在事务数据库中进行更改,提交事务始终是必要的。这就是交易的全部原则。
-
flush() 只执行插入、更新和删除语句。隔离级别适用于这些语句,就像执行的任何其他语句一样。因此,例如,如果隔离级别为 READ_COMMITTED,那么其他事务将只能看到已提交的数据。 flush() 不提交。它执行插入、删除和更新语句。
标签: java jpa entitymanager