2012-01-03 41 views
1

全部,城堡活動記錄對話

我已經通過Castle活動記錄項目(在.net中)的對話和對話範圍的區域中查看。我斷定活動記錄中的對話不能跨越不同的線程。換句話說,當我在線程A上創建對話並嘗試在線程B上使用ConversationalScope(使用線程A上創建的當前對話)時,我訪問例如在線程AI上加載的實例上的延遲集合,將獲得異常因爲檢查當前線程作用域的SesessionFactoryHolder不會爲線程B找到任何已註冊的作用域,因爲每個線程(線程靜態字段)都存儲線程作用域(在Windows窗體中)。

上述理解是否正確?如果是的話,那不是限制嗎?對話應該能夠跨越不同的線程。如果這是真的,我想問一些想法如何在多線程之間共享一個hibernate會話(使用Castle Active Record),而無需編寫大量的代碼。

編輯:我想添加到這篇文章過去對我的最新發現。以上對話不跨越線索的說法仍然成立。關於不能在另一個線程上加載懶惰集合的聲明是錯誤的。懶惰的集合可以在另一個線程上延遲加載(在線程B的這個例子中)。我發現的原因是,只要對話存在,會話也是如此,因此可以訪問懶惰的集合。

編輯2:我想通了。我會用這個答案離開我的舊帖子,以便其他對此主題有疑問的人可以受益。

答案:在城堡活動記錄框架對話可以跨線程共享。什麼情況是,在一個新的線程會話範圍始終與下面的行註冊:

ConversationalScope範圍=新ConversationalScope(currConv)

因此,當前線程具有有效的會話範圍。 SessionFactoryHolder然後被迫使用線程的當前會話作用域(而不是使用其本地會話)。檢索hibernate會話的邏輯是它將這個任務委託給會話,它將返回最後一個hibernate會話(在前一個線程A上創建)。因此,如果對話範圍有效(未處理),您將獲得由另一個線程創建的同一個會話。

這裏的示例代碼:

 
Thread A: 

IScopeConversation conv = new ScopedConversation(); 
var order = null; 

using (ConversationalScope scope = new ConversationalScope(conv)) 
{ 
    order = Order.Load(1); 
} 

// spawn/run thread B, access lazy collection on order 

Thread B: 

using (ConversationalScope scope = new ConversationalScope(conv)) 
{ 
IList orderDetails = order.Details; // will NOT cause exception since the conversation is still valid (has not been disposed) 
} 

回答

1

在城堡的活動記錄框架對話可以在線程間共享。什麼情況是,在一個新的線程會話範圍始終與下面的行註冊:

ConversationalScope範圍=新ConversationalScope(currConv)

因此,當前線程具有有效的會話範圍。 SessionFactoryHolder然後被迫使用線程的當前會話作用域(而不是使用其本地會話)。檢索hibernate會話的邏輯是它將這個任務委託給會話,它將返回最後一個hibernate會話(在前一個線程A上創建)。因此,如果對話範圍有效(未處理),您將獲得由另一個線程創建的同一個會話。