我用我的服務器上的Hibernate,(tomcat8,休眠和PostgreSQL)。 我的代碼運行的每一天結束(使用Quartz)一些代碼,該存儲過程中調用(休眠):休眠凍結在交易開始功能
public void execute(JobExecutionContext context)
throws JobExecutionException {
log.info("=========Start daily update==========");
long startTime = System.currentTimeMillis();
boolean transactionCompleted = false;
int retryCount = HibernateUtil.RETRY_COUNT;
HibernateUtil.closeCurrentEntityManager();
EntityManager em = HibernateUtil.currentEntityManager();
while (!transactionCompleted)
{
try {
em.getTransaction().begin();
dailyUpdateDao.dailyUpdate();
em.getTransaction().commit();
transactionCompleted = true;
} catch (PersistenceException ex) {
if (!HibernateUtil.isDeadlockException(ex) || retryCount == 0) {
log.error("non deadlock error", ex);
throw ex;
}
log.error("deadlock detected. Retrying {}", HibernateUtil.RETRY_COUNT - retryCount);
retryCount--;
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
try {
Thread.sleep(HibernateUtil.sleepIntervalWhenDeadlockDetected(retryCount));
} catch(Exception sleepex) {
log.error("non deadlock sleep ex", ex);
throw ex;
}
}
}
log.info("===========Daily Update Job Completed ============== It took {} ms", System.currentTimeMillis() - startTime);
}
在上面的代碼中dailyUpdate函數執行以下操作:
public void dailyUpdate() {
String sql = "select count(*) FROM daily_update()";
EntityManager em = HibernateUtil.currentEntityManager();
em.createNativeQuery(sql).getSingleResult();
}
(通過休眠調用存儲過程使用本機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()如何工作? – Andremoniy
@Andremoniy更新了問題。請看一下。 – maximus
這個類裏面的'entityManager'字段是什麼? – Andremoniy