Castle 活动记录对话

发布于 2024-12-25 04:29:38 字数 1376 浏览 0 评论 0原文

所有,

我已经浏览了 Castle Active Record 项目(在 .net 中)的对话和对话范围领域的源代码。我得出的结论是,活动记录中的对话不能跨越不同的线程。换句话说,当我在线程 A 上创建对话并尝试在线程 B 上使用 ConversationalScope(使用在线程 A 上创建的当前对话)时,例如,我访问线程 AI 上加载的实例上的惰性集合时,将会出现异常因为检查当前线程作用域的 SesessionFactoryHolder 将找不到线程 B 的任何注册作用域,因为线程作用域(在 Windows 窗体中)是按线程存储的(线程静态字段)。

上述理解是否正确?如果是,那不是限制吗?对话应该能够跨越不同的线程。如果这是真的,我想询问一些如何在多个线程之间共享休眠会话(使用 Castle Active Record)而不编写大量代码的想法。

编辑:我想在这篇文章中添加我的最新发现。上面的对话不跨线程的说法仍然成立。关于无法在另一个线程上加载惰性集合的说法是错误的。延迟集合可以在另一个线程上延迟加载(在本例中是在线程 B 上)。我发现这样做的原因是,只要对话存在,会话也存在,因此可以访问惰性集合。

编辑2:我想通了。我将在我的旧帖子中留下这个答案,以便其他对此主题有疑问的人可以受益。

答案:在城堡活动记录框架中,对话可以跨线程共享。发生的情况是,在新线程上,会话范围始终使用以下行注册:

ConversationalScope range = new ConversationalScope(currConv)

因此,当前线程具有有效的会话范围。然后,SessionFactoryHolder 被迫使用线程的当前会话范围(而不是使用其本地会话)。检索休眠会话的逻辑是,它将此任务委托给会话,该会话将返回最后一个休眠会话(在上一个线程 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)
}

All,

I have looked through source of Castle Active Record project (in .net) in the area of conversations and conversational scope. I have concluded that the conversations in active record cannot span different threads. In other words, when I create conversation on thread A and than try to use ConversationalScope (using current conversation created on thread A) on thread B where I access for example a lazy collection on an instance that was loaded on thread A I will get an exception because the SesessionFactoryHolder that checks the current thread scope will not find any registered scopes for thread B because thread scopes (in windows forms) are stored per thread (thread static field).

Is the above understanding correct? If yes, is that not limiting? Conversations should be able to span different threads. If that's true, I would like to ask for some ideas how to share a hibernate session (using Castle Active Record) across multiple threads without writing a lot of code.

EDIT: I would like to add to this post past on my latest finding. The above statement that a conversation does not span threads still holds true. The statement in regards to not being able to load lazy collections on another thread is false. Lazy collections CAN be loaded lazily on another thread (in this example on thread B). The reason for this as I discovered is that as long a the conversation lives, so do the sessions, and therefore lazy collections can be accessed.

EDIT 2: I figured it out. I will leave my old post with this answer so others who have questions about this topic can benefit.

ANSWER: In castle active record framework conversations can be shared across threads. What happens is that on a new thread a session scope is always registered with the following line:

ConversationalScope scope = new ConversationalScope(currConv)

Therefore, the current thread has a valid session scope. The SessionFactoryHolder is then forced to use the current session scope for the thread (instead of using its local session). The logic for retrieving hibernate session is that it delegates this task to the conversation which will return the last hibernate session (created on previous thread A). Hence, you get the same session that was created by another thread provided the conversation scope is valid (not disposed).

Here's the example code:

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)
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

空气里的味道 2025-01-01 04:29:38

在城堡活动记录框架中,对话可以跨线程共享。发生的情况是,在新线程上,会话范围始终使用以下行注册:

ConversationalScope range = new ConversationalScope(currConv)

因此,当前线程具有有效的会话范围。然后,SessionFactoryHolder 被迫使用线程的当前会话范围(而不是使用其本地会话)。检索休眠会话的逻辑是,它将此任务委托给会话,该会话将返回最后一个休眠会话(在上一个线程 A 上创建)。因此,如果会话范围有效(未释放),您将获得由另一个线程创建的相同会话。

In castle active record framework conversations can be shared across threads. What happens is that on a new thread a session scope is always registered with the following line:

ConversationalScope scope = new ConversationalScope(currConv)

Therefore, the current thread has a valid session scope. The SessionFactoryHolder is then forced to use the current session scope for the thread (instead of using its local session). The logic for retrieving hibernate session is that it delegates this task to the conversation which will return the last hibernate session (created on previous thread A). Hence, you get the same session that was created by another thread provided the conversation scope is valid (not disposed).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文