4

在用於運行作業的windows web服務的上下文中,我們嘗試重用我們爲Web應用程序開發的NHibernate DAL。NHibernate會話(和無狀態會話)和長時間運行的應用程序

會話管理,我們有兩個選擇,每一個有它的優點和缺點:

有狀態會話

  • 去,因爲它跟蹤的一切成長了很多(L1 /會話緩存)
  • 需要小心關閉,會話處理似乎不足以清除L1緩存(我注意到使用內存分析器)

無狀態會話

  • 目前無法重用的映射。

初始化[...]未能初始化懶洋洋角色的集合:與「懶=真正的」聲明的所有包包除了具有以下不同(儘管會議沒有被關閉)結束 [...],沒有會話或會話關閉

很顯然,我們不能更新映射(它們與Web應用程序共享)與懶惰=「假」,這會是一個巨大的缺點表演

  • 不能與二級緩存交互:當共享L2緩存將被部署,該服務將無法以無效的L2高速緩存數據的Web應用程序有NHibernate的事實證明,勁達最新數據

直到現在,我們已經成功地在Web上下文中使用有狀態會話和NHibernate LINQ,並使用結構映射來進行依賴注入。

我的問題是:

  • 是否有良好的解決方案,在一個長期運行的線程使用NHibernate的?
  • 我寧願使用有狀態會話,但如何避免內存泄漏?

回答

2

問題解決了!其實有幾個問題。

第一個是有關情況範圍,多線程:

  • 爲每個線程創建一個新的會話。
  • 只要線程完成其工作,清除所有連接到線程的實例。使用StructureMap,在線程內,使用new HybridLifecycle().FindCache().DisposeAndClear();。它會導致連接到該線程的會話關閉並處理。
  • 當生命週期是線程作用域時,StructureMap使用ThreadStatic變量來保持對對象高速緩存的引用。所以訣竅是在線程中調用StructureMap的ObjectFactory。最初,在我們的應用程序中,主線程負責創建新線程,並調用ObjectFactory。這是我們所犯的重大錯誤,並且一旦他們的工作完成,確實無法清理線程。

會話類型:

  • 無需使用StateLessSession,只要實例都經過精心佈置的狀態會話。在我們的例子中,StatelessSession有太多的缺點(高速緩存管理是主要的)

重要說明:小心實例化NHibernate NHibernate會話工廠只有一次!

當NHibernate實例被仔細管理時,沒有內存泄漏。

0

在長時間運行的進程中保持有狀態會話不變是一個好主意。

我的建議是重新設計您的流程,以將與數據庫相關的代碼與非數據庫相關的代碼分開,以便任何與數據庫相關的操作都可以保留在短期會話中。

相關問題