Dear All ,
I am highly confused while reading the subject "Concurrent Access to an Entity Bean " .
First let me how much the Depolyment element "Reentrant" is related to concurrent access ?
When an enity bean is deployed as non-reentrant , is concurrent access( from client point of view ) possible on that bean ? My understanding it is highly possible. re-entrant indicates some thing like SingleThreadModel . In this case container will either serialize ( means put the calls in a queue - not a good approch) or allocate a new instance to serve the request . Now if the call was not in a transactional context allocating a new is not a big problem.
If both the call(s) are in transactional context , then what will happen ? If the container left the synchronization upon the underlying RDBMS then all these issues are handled by RDBMS itself.
But if the container does not left it for RDBMS when how it is handled ?
What happens in the previous cases when entity bean is deployed as reentrant.
Thanks in Advance
Re-entrancy *should* never be related to concurrent access to a bean instance. EJB never permits concurrent access to an instance. Re-entrancy should be used when callbacks are required: where the bean calls a different component, which calls back into the bean. However, because the container can't tell the difference between a callback and a concurrent call (within the same transaction), re-entrancy *could* cause concurrent calls. Such calls are not permitted (you as a developer should not make them) and the behaviour of the App server when such a call is made is undefined.
"Concurrent access to an entity bean" refers to the entity itself, not the bean instance. Multiple transactions can access the same *entity* concurrently - but they will not access the same instance. The container will assign a different instance to each transaction. The relation to re-entrancy is this: EJBs transaction model assumes a sinlge thread of execution for each transaction. If this is true, there will be no problem. If you break this assumption somehow and your entity is not re-entrant, results are predictable: the second call will fail (or possibly get enqueued). If your bean is re-entrant, you can get a case where a single bean executes concurrent threads, and that can lead to all sorts of problems.
waw. That's a good explanation. Why did you stop? I'm kind of interested in multi-thread-concurrent-access instances. Is there any way to achieve that? To allow different client calls to one single instance? Something like a singleton ejb?
No, EJB's are single threaded. Either each client will access a different instance or else the requests to the single instance will be serialised by the container.
No, there is no way to achieve that, atleast not portably. As I mentioned, EJB never *allows* concurrent access to instances. The only rare case where an EJB server is not *required* to deny such concurrency is when two requests with the same transaction context are made to a re-entrant entity bean. That doesn't mean EJB *allows* concurrent access to an instance in that scenario: it only means the App server is not required to avoid it (because it can't). You as a developer are required not to make such calls. If you do make them, behaviour is undefined.
I hope that clears it. Feel free to post follow-ups.
Thanks to every body for their explanation.
Let us assume the secnario .
Client C1 calls entity bean A ( by findByPrimaryKey)
calls a method on A say m1();
m1 calls entity bean B ( by findByPrimaryKey )
m1 calls a method on B say m2();
now m2() again calls entitybean A method m3()
by looking up home object and the findByPrimaryKey
with same primary key as client c1 called A.
As per as the JVM is concerned , Object instance
assigned in m3() id different than object instance
assigned for client C1 call but entity is same.
Will this be considered as reentrant call ? I am considering that all calls are in same transactional context . If it is not in same transactional context then
this will not be considered as reentrant .
I am also wondering how container managed the secnario when
it is in culsterd env .. then seconf instance may be in a
different server it self ...
In this case, if the bean is reentrant, m3() could be called on the same instance that the made the original m1() call. This is eaxctly what re-entrancy is used for: making callback calls.
The container can manage this scenario in any number of ways. The simple one is to simply direct all requests to the same instance (that is, all requests with the same transaction context). The container can also keep several instances for the same transaction, and synchronize them by making them ejbStroe()/ejbLoad() after each request. Most containers will use the first approach, and besides it shouldn't matter much to you (as a developer).
so now i am convinced an ejb is single threaded, explain me this: why does j2ee not provide a thing that allows
1) remote method calls (like ejb)
2) declarative transaction support (like ejb)
3) multi threaded access (like servlets)
I mean, if i know my stateless session ejb does not use private state during method invocations, what's the use of the ejb container using many instances to handle concurrent calls?