Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate 使用实体管理器刷新时事务中空闲_Hibernate_Jpa_Transactions - Fatal编程技术网

Hibernate 使用实体管理器刷新时事务中空闲

Hibernate 使用实体管理器刷新时事务中空闲,hibernate,jpa,transactions,Hibernate,Jpa,Transactions,我们使用Hibernate、c3p0、postgresql作为持久层。 在运行数据密集型作业(主要是select/insert)时,一位开发人员决定在提交之前使用entityManager.flush(),如下所示 entityManager.getTransaction().begin() insert n elements entityManager.flush() entityManager.getTransaction().commit() 过了一会儿,所有运行数据密集型作业的线程似乎

我们使用Hibernate、c3p0、postgresql作为持久层。 在运行数据密集型作业(主要是select/insert)时,一位开发人员决定在提交之前使用entityManager.flush(),如下所示

entityManager.getTransaction().begin()
insert n elements
entityManager.flush()
entityManager.getTransaction().commit()
过了一会儿,所有运行数据密集型作业的线程似乎都被阻塞了,我们发现它们正在等待池中的数据库连接。 池中处于“事务中空闲”状态的所有连接。 这种情况每次都可以复制

在移除flush()之后,情况消失了

有人知道为什么会这样吗


谢谢:D

hibernate有一个智能缓存系统,它只需收集要执行的sql命令列表,然后在提交时执行。Flush用于继续并部分执行这些命令。这可能会有帮助,但是当你考虑到Hibernate在没有刷新的情况下不做任何事情,那么你就导致数据库不得不处理短突发的大事务而不是一次处理。 这就相当于把一张纸交给你的同事去撕碎,而不是让他一次撕碎多张纸。将此与数据库可能在事务中间锁定记录的事实相结合,从第一次调用刷新的那一刻起,数据库就致力于执行命令直到您提交为止。如果数据库没有等待您,并且同时拥有所有命令,那么它可以在完成实际工作所需的时间内完成


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

那么,当我们刷新时,为什么hibernate挂起在事务中呢?这不应该是一只虫子吗?@ibrabeicker如果它挂起,那么它就是一只虫子。虽然你应该确定这不仅仅是一个需要时间才能完成的繁重的操作,而且它实际上是挂起的。如果是这样的话,可能有一些记录被锁定,无法完成插入。因此,hibernate使用基本的CrudRepository方法插入30条记录只需不到一秒钟的时间。它用10秒来记录1000条记录。在这种规模下,将1亿条记录插入我的一个简单Oracle表(它有一个命名索引和一个整数主键)需要10天以上的时间。我认为hibernate不够聪明,无法直接完成批处理作业。你找到答案了吗?我也有类似的问题:我们也看到了类似的情况。