Java Hibernate在事务开始时冻结功能
我正在服务器上使用Hibernate(tomcat8、Hibernate、postgresql)。 每天结束时,我的代码都会运行(使用Quartz)一些代码,这些代码在存储过程内部调用(hibernate): 上述代码中的dailyUpdate函数执行以下操作: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
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,它打开了新的连接,但没有关闭它。所以基本上你的池中没有免费的连接
只需尝试moveHibernateUtil.closeCurrentEntityManager()编码>进入final{…}
块并再次测试。什么是HibernateUtil
以及closeCurrentEntityManager()
和currentEntityManager()
如何工作?@Andremoniy更新了问题。请看一看。这个类中的entityManager
字段是什么?@Andremoniy它在代码中:ThreadLocal entityManager=new ThreadLocal();哦,我以为是我做的,但一开始就放错了。。。非常感谢。
em = emf.createEntityManager();