3

我们将 hiberante、c3p0、postgresql 用于持久层。在运行数据密集型作业(主要是选择/插入)时,其中一位开发人员决定在 commit 之前使用 entityManager.flush() ,就像这样

entityManager.getTransaction().begin()
insert n elements
entityManager.flush()
entityManager.getTransaction().commit()

一段时间后,所有运行数据密集型作业的线程似乎都被阻塞了,我们发现它们正在等待来自池的数据库连接。池中处于“空闲事务”状态的所有连接。这种情况每次都可以复制。

删除 flush() 后,情况消失了。

有谁知道为什么会发生这种情况?

感谢:D

4

1 回答 1

4

hibernate 有一个智能缓存系统,它简单地收集要执行的 sql 命令列表,然后在提交时执行它们。Flush 用于继续并部分执行这些命令。看起来这可能会有所帮助,但是当您认为 hibernate 在没有刷新的情况下提交之前什么都不做,那么您将导致数据库必须在短时间内处理大型事务,而不是一次处理所有事务。

这相当于将单张纸交给您的同事进行撕碎,而不是让他一次撕碎多张纸。结合数据库可能会在事务中间锁定记录的事实,从您第一次调用刷新的那一刻起,数据库将致力于执行命令的任务,直到您提交。如果数据库没有在等待您并且一次拥有所有命令,它可以在完成实际工作所需的时间内完成。

简而言之,hibernate 知道它在做什么。Flush 会覆盖休眠的正常功能,如果您不小心,实际上会降低性能。如果顺序很重要(例如在插入之前执行删除),您可能应该只使用刷新。

于 2012-09-12T10:05:57.497 回答