내 서버 (tomcat8, hibernate, postgresql)에서 최대 절전 모드를 사용하고 있습니다. 내 코드가 실행되는 일의 모든 끝 저장 프로 시저 내에서 호출하는 코드 (석영을 사용) (최대 절전 모드) :트랜잭션 시작 함수에서 최대 절전 모드로 전환
public void dailyUpdate() {
String sql = "select count(*) FROM daily_update()";
EntityManager em = HibernateUtil.currentEntityManager();
em.createNativeQuery(sql).getSingleResult();
}
:
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 기능은 다음을 수행한다
(최대 절전 모드에서 원시 SQL을 사용하는 저장 프로 시저 호출).
서버를 실행할 때 처음 2 ~ 3 번은 정상적으로 호출됩니다. 다음 호출은 끝나지 않습니다. 저는 로컬로이 문제를 재현했습니다. 매일 1 분마다 작업을 시작하는 일정을 정했습니다. 그것은 나에게 다음과 같이 기록 하였다 :
매일 업데이트 작업 ============== 완료 그것은 7338했다
는 매일 업데이트 작업 완료 MS ======= =======은 6473 MS
...
매일 업데이트 작업 ============== 완료 그것은했다 183381 MS
했다 그래서 지연이 증가했고 내부적으로 진행되는 것을보기로 마음 먹었다. 이자형. 이유는 무엇
어떻게 해결하는 방법 : 그것이 완료 결코
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