Concurrent access to session EJBs disallowed ?
I'm developing a web based application that uses multiple frames in a
browser window. Three of those frames go to a stateful session EJB to get
the data to be displayed in them (it's different data that's all held in a
common session).
What I'm finding is that I often get an exception thrown when trying to
invoke a method on the session EJB from one or more of the JSPs:
weblogic.ejb.extensions.LockTimedOutException: Lock for primaryKey:996674553807_2
could not be acquired without waiting.
This doesn't seem to be a Weblogic-specific problem: I've looked around in
various discussion groups, and have found that this is apparently correct
behavior. According to the EJB 1.1 (and 2.0) spec, it is documented behavior
that the EJB container should throw a java.rmi.RemoteException if a client
tries to invoke more than one method at the same time in an instance of a
session EJB (the LockTimedOutException above extends RemoteException).
An excerpt from the EJB 1.1 spec (section 6.5.6, "Serializing session bean methods"):
"Clients are not allowed to make concurrent calls to a session object. If a
client-invoked business method is in progress on an instance when another
client-invoked call, from the same or different client, arrives at the same
instance, the container must throw the java.rmi.RemoteException to the
second client."
The question I have is: how can this be ? My intuition would be that the
EJB container should manage access to EJBs similarly to how thread
synchronization works: it should block additional accesses until the first
access finishes.
I can't be the only developer in the world that has multiple JSPs in a
framed window all banging on a session EJB at the same time. What have
other people done to work around this problem ? Session EJBs are supposed
to maintain conversational state; does this really mean that I can't access
this state from more than one window at a time in my client application ?
My current solution is to wrap invocations to the session EJB in a "while"
loop and retry a certain number of times until the operation succeeds. This
works pretty well, but it makes the code nasty and doesn't really resolve
the basic problem: it's clearly a race condition, and with enough bad timing
some operations will always exceed their max retries and fail.
Is there any prospect that this will change in future revisions of the EJB
spec ? This seems much too restrictive for enterprise applications written
on an inherently multithreaded platform like Java.

