2010-01-06 57 views
2

在我們的系統中,我們有多線程處理引擎。在處理期間,每個線程都會調用方法從數據庫中檢索數據。我們確定,如果從同一線程調用的方法使用相同的數據庫會話(會話來自當然池),性能會大大提高。如何確保從同一線程調用的方法使用相同的DB會話

Spring中是否有任何標準的方法來確保這樣的事情,或者我們必須提出自己的定製解決方案?

更新:忘了提,同樣的方法,可以在不同的上下文中調用,他們應該使用池中

+0

你是指休眠會話嗎?如果是這樣,你可以使用hibernate中的current-session概念來維護每個線程一個會話。 – Yoni 2010-01-06 18:54:15

+0

@Yoni查看我的問題更新。那麼它將如何工作? – 2010-01-06 19:01:15

+0

我很驚訝,性能更好。我假設每個方法的模式是這樣的: 從池中獲取數據庫, ,做數據庫工作 ,提交/回滾 ,返回到池。 是這樣嗎? – Dave 2010-01-06 19:28:46

回答

2

我沒有看到春天在你的問題的任何地方。所以我假設你想要一個簡單的工具來做到這一點。

class SessionUtil { 
    private ThreadLocal currentSession; 

    public Session getCurrentSession() { 
     if(currentSession.get() == null) { 
      Session s = //create new session 
      currentSession.set(s); 
     } 
     return (Session)currentSession.get(); 
    } 
} 

線程本地將確保在同一線程內它始終是相同的會話。如果你使用Spring,那麼上面提到的類/實用程序(在其他響應中)應該是完美的。

+0

他的問題是使用spring標記的**。 – BalusC 2010-01-12 17:12:07

+0

這是我們討論過的解決方案之一,但我希望能在Spring中找到一些讓它透明的東西 – 2010-01-12 19:36:28

0

春3.0獲取會話的標準方式具有線程範圍豆(hovewer的概念,這範圍默認情況下不註冊,請參閱文檔):3.5 Bean scopes3.5.5.2 Using a custom scope

編輯: 我說這個:

線程範圍的bean從Spring 3.0開始, 有一個線程範圍可用,但是默認情況下未註冊爲 。有關更多 信息,請參閱 SimpleThreadScope的文檔。有關如何註冊此 或任何其他自定義範圍的說明,請參閱 Section 3.5.5.2, 「Using a custom scope」

2

春天有一個類叫做TransactionSynchronizationManager。它將當前的Session存儲在ThreadLocal中。不建議開發人員使用TransactionSynchronizationManager,但可以嘗試使用它。

Session session = ((SessionHolder) 
    TransactionSynchronizationManager.getResource(sessionFactory)).getSession(); 

(如果你使用EntityManager,簡單地加上 「EntityManager的」 替換 「會議」)。

您可以在您的bean中注入sessionFactory - 它是按應用程序提供的。

看看this的討論。

其他選擇,我認爲這是最好的手動線程處理是:

0

春季座標數據庫會話,連接和線程通過它的Transaction Framework(實際上,利用其TransactionSynchronizationManager - 見描述here - 但你真的不想惹直接,這是可怕的)。如果你需要協調你的線程,那麼這是迄今爲止最簡單的方法。

但是,如何選擇使用該框架已成爲您的首選。

相關問題