What's true about Container suppor for messagge-driven beans?
The Container must ensure that the bean instances are non-reentrant.
What does reentrant mean?
It means that at any time, only one thread can be executing an instance. So I can't have two threads executing the MDB at the same time.
Is there other ejb type that use reentrant option?
Entity beans are re-entrant. Makes sense doesn't it? Entity beans represent entities in the data store. We should be able to allow multiple clients to be able to read the contents of a particular entity at the same time.
Reentrant means that an instance can allow a loopback. A loopback is where Bean #1 calls methods on Bean #2 and Bean #2 turns around and calls methods back on Bean #1, all within a single thread of control.
The Bean Provider must declare in the deployment descriptor if the bean is reentrant (True or False). Entity beans are the only beans with the <reentrant> tag. Session beans are always nonreentrant and will throw an exception. Entity beans marked as reentrant False will throw an exception as well if you try to perform a loopback.
A great negative about allowing reentrancy is that the Entity Bean can't tell the difference between an application client (physical user) and an EJB client (possible loopback). This means if you allow reentrancy you also allow multithreaded (and multiclient) access of your bean which can cause serious data issues! The spec discourages using reentrant True.
Message-Driven Beans can never have reentrancy (or loopbacks) because the client is disconnected from the bean instance. In a way, the container becomes the new client but for the test "MDBs don't have clients"! The container makes a new thread out of each MDB call. The spec simply points out that reentrancy is not an issue for MDB because each Message gets its own thread and the container only allows one thread per instance at any given time.
As u said the loopback "all within a single thread of control". Why allow reentrancy can allow multithreaded (and multiclient) ?
My line preceding it says: ...the Entity Bean can't tell the difference between an application client (physical user) and an EJB client (possible loopback).
I really should have said that the container can't tell the difference, but my point is still valid. The container can't distinguish one from the other, so it must let them both in if you want to allow reentrancy.
Pages 189-190 of the spec say:
Re-entrant entity beans must be programmed and used with caution. First, the Bean Provider must code the entity bean with the anticipation of a loopback call. Second, since the container cannot, in general, tell a loopback from a concurrent call from a different client, the client programmer must be careful to avoid code that could lead to a concurrent call in the same transaction context.
Concurrent calls in the same transaction context targeted at the same entity object are illegal and may lead to unpredictable results. Since the container cannot, in general, distinguish between an illegal concurrent call and a legal loopback, application programmers are encouraged to avoid using loopbacks. Entity beans that do not need callbacks should be marked as non-reentrant in the deployment descriptor, allowing the container to detect and prevent concurrent calls from clients.
I hope this answers your question, Vince.
Joined: Feb 11, 2003
Thx Marc !
I think I have a wrong concept of the concurrent call. Yr response do help me a lot. But I still have serveral points to ask to make my concept correct.
The container cannot, in general, tell a loopback from a concurrent call from a different client, the client programmer must be careful to avoid code that could lead to a concurrent call in the same transaction context.
1. Can I say "A loopback call of a entity bean" IS-A kind of "Concurrent call"
2. There is a Concurrent call from a different client in the same transaction. Under what situation will that happen (in the same transaction)? Happy that someone can provide a simple code illustrate the flow.
3. Refer to pt. 2, What happen if there is a Concurrent call from a different client in the *DIFFERENT* transaction ?