JPA flush和commit的区别

12

在JPA中,如果我们调用EntityTransaction.commit(),是否会自动调用EntityManager.flush()?或者我们应该同时调用它们两个?它们之间有什么区别?因为我在使用JPA时遇到了问题,当我将实体插入数据库时,我调用persist()。在数据库中,数据已经被插入(可以获取),但这些数据并没有显示在我的应用程序中(我使用findAll()进行获取)。而在另一个实体中,则正常显示。我需要了解更多的信息吗?我正在使用标准的Spring CRUD、JPA resource_local和PostgreSQL。抱歉我的英语表达,谢谢


你的回答和@singhakash不同。那么什么是最佳实践? - monterico
3个回答

20

1
链接已经失效了,你能否更新一下? - Abimaran Kugathasan

18
如果我们调用EntityTransaction.commit(),它会自动调用EntityManager.flush()吗?
是的。
有什么区别?
在flush()中,数据的更改在遇到flush后反映在数据库中,但它仍然处于事务中。必须将flush()放在事务上下文中,并且除非需要(在极少数情况下),否则您不必显式执行它,因为EntityTransaction.commit()会替您执行此操作。 来源

10
如果您的实体中有一个带有@Version注释的列,并调用entityManager.flush(),则您将立即获得OptimisticLockException,或者数据库将锁定此行(或表)。在后一种情况下,您仍然可以调用setRollbackOnly(),锁定稍后将在没有DB更改的情况下释放。
或从另一个角度来看,使用flush()可以在数据库行上创建(悲观)锁定。其他人仍会看到旧条目,但如果他们尝试更新,则会被阻止,直到锁定被释放为止。
所有这些对于CMT(容器管理的事务)也是正确的。您可以在服务方法中调用flush()(甚至多次),并立即处理OptimisticLockException(s),而不是等待服务方法完成和CMT提交执行的时刻。

2
这个答案跟问题几乎没关系,但是无论如何还是非常有用的。 - giannis christofakis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接