Details
-
Type:
Bug
-
Status: Resolved (View Workflow)
-
Priority:
Major
-
Resolution: Done
-
Affects Version/s: 1.1.0.Final
-
Fix Version/s: 1.1.3.Final
-
Labels:None
Description
Concurrent calls to a @ConversationScoped component:
Thread 1:
AbstractConversationContext.activate(String cid)
ConversationImpl.lock(long timeout) <-- returns true
correctly proceed inside method
Thread 2:
AbstractConversationContext.activate(String cid)
ConversationImpl.lock(long timeout) <-- returns false but activate() does not check result !!!
incorrectly proceed inside method
I think AbstractConversationContext.activate(String cid) should check the result of ConversationImpl.lock(long timeout) and not allow the second thread to proceed.
From BusyConversationException javadoc:
Indicates that the container has rejected a request because a concurrent request is associated with the same conversation context.
The container ensures that a long-running conversation may be associated with at most one request at a time, by blocking or rejecting concurrent requests. If the container rejects a request, it must associate the request with a new transient conversation and throw an exception of type BusyConversationException from the restore view phase of the JSF lifecycle.
So I think that AbstractConversationContext.activate() should throw BusyConversationException which should caught, handled and re-thrown in WeldPhaseListener. Something like:
try
{
conversationContext.activate(cid);
}
catch(BusyConversationException bce)
{
conversationContext.deactivate(); // XXX what else here ?
throw bce;
}
}