Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.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
Java Hibernate在事务开始时冻结功能_Java_Postgresql_Hibernate_Quartz Scheduler - Fatal编程技术网

Java Hibernate在事务开始时冻结功能

Java Hibernate在事务开始时冻结功能,java,postgresql,hibernate,quartz-scheduler,Java,Postgresql,Hibernate,Quartz Scheduler,我正在服务器上使用Hibernate(tomcat8、Hibernate、postgresql)。 每天结束时,我的代码都会运行(使用Quartz)一些代码,这些代码在存储过程内部调用(hibernate): 上述代码中的dailyUpdate函数执行以下操作: public void dailyUpdate() { String sql = "select count(*) FROM daily_update()"; EntityManager em = H

我正在服务器上使用Hibernate(tomcat8、Hibernate、postgresql)。 每天结束时,我的代码都会运行(使用Quartz)一些代码,这些代码在存储过程内部调用(hibernate):

上述代码中的dailyUpdate函数执行以下操作:

public void dailyUpdate() {
    String sql = "select count(*) FROM daily_update()";
    EntityManager em = HibernateUtil.currentEntityManager();
    em.createNativeQuery(sql).getSingleResult();
}
(通过hibernate使用本机sql调用存储过程)

当我运行服务器时,它通常会进行前2或3次调用。下一个电话永远不会结束。我在本地复制了这个问题,而不是每天,我把时间表改为每1分钟开始一次任务。它向我展示了如下日志:

每日更新作业已完成=================耗时7338毫秒

每日更新作业已完成=================耗时6473毫秒

每日更新作业已完成=================耗时183381毫秒

所以延迟增加了,我决定看看里面发生了什么。 在上面的代码中,当它尝试执行

em.getTransaction().begin();
它永远不会结束,堆栈跟踪如下图所示:

原因是什么?如何解决

编辑1:currentEntityManager和closeCurrentEntityManager代码:

public class HibernateUtil {
...
private static EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(PERSISTENT_UNIT);
public static EntityManager currentEntityManager(EntityManagerFactory emf)
        throws HibernateException {
    EntityManager em = (EntityManager) entityManager.get();
    if (em == null||!em.isOpen()) {

        em = emf.createEntityManager();

        entityManager.set(em);
    }
    return em;
}

public static void closeCurrentEntityManager() {
    EntityManager s = (EntityManager) entityManager.get();
    try {
        if (s != null) {
            if (s.getTransaction().isActive()) {
                if (s.getTransaction().getRollbackOnly()) {
                    s.getTransaction().rollback();
                } else {
                    s.getTransaction().commit();
                }
            }
            s.close();
        }
    } finally {
        entityManager.remove();
    }
}

好的,很好,在发布了关于什么是
HibernateUtil
的详细信息之后,
closeCurrentEntityManager()
currentEntityManager()
如何工作,以及这个类中的
entityManager
域是什么,一切都变得清晰了

看看你的代码。首先关闭“当前”实体管理器:

HibernateUtil.closeCurrentEntityManager()

但是您应该考虑到这样一个事实,
quartz scheduller
在不同的线程中启动其任务。所以

public static void closeCurrentEntityManager() {
    EntityManager s = (EntityManager) entityManager.get();
将返回
null
(如果是新线程)

您调用的下一步

 EntityManager em = HibernateUtil.currentEntityManager();
这也将创建新的
EntityManager
,因为它是新线程:

em = emf.createEntityManager();
现在看看您的屏幕截图:您的
beginTransaction()
方法正在等待新的连接。这里发生的事情是,您创建了新的entitmanager,它打开了新的连接,但没有关闭它。所以基本上你的池中没有免费的连接


只需尝试move
HibernateUtil.closeCurrentEntityManager()进入
final{…}
块并再次测试。

什么是
HibernateUtil
以及
closeCurrentEntityManager()
currentEntityManager()
如何工作?@Andremoniy更新了问题。请看一看。这个类中的
entityManager
字段是什么?@Andremoniy它在代码中:ThreadLocal entityManager=new ThreadLocal();哦,我以为是我做的,但一开始就放错了。。。非常感谢。
em = emf.createEntityManager();