문제

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

도움이 되었습니까?

해결책

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top