EntityManager. Does Flush() save data in database as Commit()?
我已经浏览了有关entityManager.flush()方法的许多主题。
在我的实践中,我一直使用过persist()和commit()方法。
我也发现有时flush()在对数据库的选择请求期间自动执行,并且此时它检查数据库的约束,因此,如果由于选择期间的约束而导致持久化对象错误,则将引发异常。
其实我想了解:
当您执行flush()方法时,持久化的数据是否会保存在数据库中? 所以您不需要在flush()之后执行commit()吗?
在某些具体情况下,使用flush()而不是commit()有什么优点?
-
persist()只是告诉实体管理器:这必须在事务结束之前保存一些时间。 flush()执行将内存中的更改复制到数据库中所需的insert / update / delete语句。 Commit提交事务,以使所有这些更改永久生效,并且对其他事务可见。 flush()不仅仅执行SQL语句。就像使用JDBC一样。
-
谢谢。我认为您享有很高的声誉和很多知识。我已经在某处阅读了相当不错的答案,但可能是由于我的经验不足,所以我不了解这是什么。我不明白什么插入/删除/更新语句可能执行flush(),因为我没有设置任何内容。我只是看到有时使用flush()而不是commit()。因此,您能否在我的问题中更详细地回答2分。特别是如果我执行flush()而不是commit(),是否将我的数据保存在数据库中而无需进一步提交?使用flush()之后是否需要做commit()?
-
您不执行任何语句,因为JPA会为您执行它们。当您通过em.get()加载实体时,它会为您执行一条SQL语句,以从数据库加载数据,对吗?这将返回一个受管实体(让我们说一个用户)。现在,如果执行user.setName("Kirill"),则可以修改内存中的对象,但是JPA还必须修改数据库中的相应行,对吗?这就是JPA的重点。
-
每次调用setter时,它都无法执行更新语句:这将导致糟糕的性能。因此它可以记住内存中的更改。 flush()告诉JPA在数据库中执行必要的更改。使用insert / update / delete语句将内存中所做的所有更改写入数据库。但是在提交事务之前,这些更改仍可以回滚。
-
好。因此,要将数据永久保存在数据库中,必须在flush()之后执行commit()吗?
-
您几乎不必显式地冲洗()。默认情况下,JPA在提交之前为您刷新了。无论您使用什么API在事务数据库中进行更改,提交事务始终是必需的。那就是整个交易原理。
-
大!非常感谢。现在我有了一个了解。我可以再问一个问题-如果我执行flush(),然后其他事务是否看到刷新的数据(如果使用了Oracle的默认隔离级别)?
-
flush()仅执行插入,更新和删除语句。隔离级别适用于这些语句以及执行的任何其他语句。因此,例如,如果隔离级别为READ_COMMITTED,则其他事务将仅看到提交的数据。 flush()不提交。它执行插入,删除和更新语句。
-
谢谢。如果您愿意并且有时间,您可以形成我会接受的答案,也许会对其他人有所帮助。如果您不愿意,我会根据您的评论以及对您的引用来创建答案。
多亏了JB Nizet,现在对flush()有了一些清晰的认识。
这里有几点:
为了将数据永久保存在数据库中,JPA需要使用
插入/更新/删除语句,然后提交此数据。
提交交易始终是必要的。
Flush()方法仅执行insert / update / delete语句而不提交数据,因此可以回滚事务和数据。
当您执行commit()时,JPA将在执行提交(即flush()方法)之前刷新数据。
在flush()期间,将在执行sql语句并将数据放入数据库时检查数据库中的约束。
当在执行flush()之后将隔离级别设置为READ_COMMITTED数据时,由于flush()不提交数据,因此在其他事务中看不到该数据。