Ich benutze Hibernate auf meinem Server, (Tomcat8, Hibernate, Postgresql). Jedes Ende des Tages mein Code ausgeführt wird (unter Verwendung von Quarz) einen Code, der innerhalb der gespeicherten Prozedur aufruft (Hibernate):Hibernate friert bei Transaktion beginnen Funktion
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);
}
Die dailyUpdate Funktion in dem obigen Code wird folgendes tun:
public void dailyUpdate() {
String sql = "select count(*) FROM daily_update()";
EntityManager em = HibernateUtil.currentEntityManager();
em.createNativeQuery(sql).getSingleResult();
}
(Aufruf der gespeicherten Prozedur mit nativen SQL durch den Ruhezustand).
Wenn ich den Server austrage, macht es normalerweise 2 oder 3 Anrufe. Die nächsten Anrufe enden nie. Ich habe das Problem lokal reproduziert, anstatt jeden Tag den Zeitplan zu setzen, um die Aufgabe jede Minute zu starten. Es hat mir gezeigt, wie diese protokolliert:
Daily Update Auftrag abgeschlossen ============== Es dauerte 7338 ms
Daily Update Auftrag abgeschlossen ======= ======= Es dauerte 6473 ms
...
Daily Update Auftrag abgeschlossen ============== Es dauerte 183.381 ms
So nahm die Verzögerung zu und ich entschied mich zu sehen was passiert ist e. In dem obigen Code, wenn es die
em.getTransaction().begin();
es nie und den Stack-Trace beendet auszuführen versucht, unten als Bild gezeigt:
Was ist der Grund, und wie zu lösen das Problem?
EDIT 1: currentEntityManager und closeCurrentEntityManager Codes:
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();
}
}
Was ist 'HibernateUtil' und wie funktionieren' closeCurrentEntityManager() 'und' currentEntityManager() '? – Andremoniy
@Andremoniy hat die Frage aktualisiert. Bitte schau es dir an. – maximus
Was ist das Feld "entityManager" in dieser Klasse? – Andremoniy