Just making sure that I understand the spec.
Given an instance of an MDB that is registered for a particular topic and given
a client that publishes two messages on this topic, it is possible that mdb1 might receive zero,
one or two messages.
I am thinking about pooling provided by the server. If the server has in its pool two
instances of Mdb class it might choose (for example) to have mdb1 process the first message
and seeing that mdb1 is busy when the second message arrives have mdb2 process it.
Is this correct?
You are correct.
The MDB can even receive messages out of order.
I understand the out of order bit, the fact that an instance of an MDB can completely
miss messages sounds more fundamental to me. The statelessness here is complete.
Anyway, a follow up question, suppose that I need to perform a task once predefined messages
(note the plural) have arrived. Now, I assume that I should keep state in some place
and check it from my MDBs. What are the options (except the obvious DB). Can I drive a
Statefull Session Bean from an MDB? Will such approach work in a clustered environment?
I would say that a statefull session bean is not an option even in a non-clustered environment. Since the MDB behaves like a stateless sb, there is no "conversation" between the MDB and any statefull sb. Every time the MDB handles a message, it is as if the MDB was just born, and the MDB can have no knowledge of any previous exchange between it and a statefull sb.
Shared state across multiple (possibly even parallel) invocations of a stateless service (like a MDB), would preferably be stored in a shared persistent object like an entity bean.
"Shared state across multiple (possibly even parallel) invocations of a
stateless service (like a MDB), would preferably be stored in a shared
persistent object like an entity bean."
In other words, the DB is the only option? If this is the case, then it seems that
the asynchronous functionality introduced in EJB 2.0 is fairly weak.
To trigger processing after a set of messages has been consumed, I am required
to define and maintain appropriate tables in the DB and possibly some entity
beans. I can easily think of situations when this approach is not natural,
to put it mildly.
some thoughts on JMS/MDB's:
- even though the JMS spec says order is not guaranteed, your JMS provider might add some value beyond the spec and guarantee order. IBM MQ Series guarantees order.
- your EJB server might allow you to limit the number of instances of your MDB to 1, thereby preventing any parallel processing.
I don't know if any of the above would simplify your situation.
As for saving state, to trigger processing when some combination of messages has arrived, if you want this chain of steps to be:
I see no other practical option other than storing state in a transactional persistent store (like a Relational DB).
If you have the further requirement of ensuring that the "process":
- happens once and only once
- no messages are ever lost
then there is even more benefit in using the MDB/Entity bean combination, if you have an EJB server and JMS provider that can coordinate transactions (like Websphere and JMS/MQ).
If your requirements are less strict, maybe you can get away with:
- limiting the MDB instances to 1
- storing your state in memory