2011-06-16 57 views
3

我在問我應該如何處理後臺線程在我的Hibernate/Spring Web應用程序中執行涉及數據庫的任務。如何處理Hibernate/Spring應用程序中的後臺線程

目前我正在使用下面的攔截器,所以我可以用@OpenSession註釋我的線程運行方法,應該打開一個會話。這也應該適用於RMI請求,例如或者在沒有打開會話的情況下調用的任何其他方法。但是,我不確定代碼是否正確,我面臨的問題是有時會話只是沒有關閉並且永遠打開。

@Around("@annotation(openSession)") 
    public Object processAround(ProceedingJoinPoint pjp, OpenSession openSession) throws Throwable { 

     boolean boundResource = false; 
     Session session = null; 

     // Bind the session to the thread, if not already done 
     if(TransactionSynchronizationManager.getResource(sessionFactory) == null) { 
      log.debug("Opening Hibernate Session in method "+pjp.getSignature()); 

      session = SessionFactoryUtils.getSession(sessionFactory, true); 
      TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session)); 
      boundResource = true; 
     } 

     // Invoke the annotated method 
     Object ret; 
     try { 
      ret = pjp.proceed(); 
     } 
     catch(Throwable t) { 
      // Rethrows the Exception but makes sure the session will be closed 
      SessionFactoryUtils.closeSession(session); 
      log.debug("Closing Hibernate Session in method (Exception thrown) "+pjp.getSignature()); 
      throw t; 
     } 

     // If a resourc was bound by this method call, unbind it. 
     if(boundResource) { 
      //SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory); 
      session.flush(); 
      SessionFactoryUtils.closeSession(session); 

      log.debug("Closing Hibernate Session in method "+pjp.getSignature()); 
     } 

     return ret; 
    } 
+1

你爲什麼需要它?你不能只使用'@ Transactional'嗎? – axtavt 2011-06-16 16:53:54

+0

這會爲我打開一個會話嗎?如果會話已經存在會發生什麼? – Erik 2011-06-16 16:56:52

+0

據我瞭解,它基本上與你的代碼完全一樣。 – axtavt 2011-06-16 17:06:02

回答

1

是的,你建議的解決方案應該工作(我自己做了一些非常類似的事情)。如果您只使用@Transactional,那麼對於每個事務,您將得到一個新的EntityManager,如果您的後臺線程有很多事務,則這不一定是最佳的。

1

Hibernate會話和JDBC連接不是線程安全的。您應該堅持每個線程的連接和會話。

相關問題