I guess the "Required" and "NoSupported" are the only two transaction attributes allowed in MDB, onMessage() method.
But confusion is that "RequiresNew" makes more sense because it will always start a new transaction and MDB's doesnot have any clients.
Only drawback this attribute has is that container has to suspend the previous transactions and which can cause overhead, but as MDB never propagate an existing existing exception, so by using "RequiresNew" there will be always a new transaction created, so why "Required" is used instead of "RequiresNew" ???
I agree with you on this. Also, I think Never is better suited for an MDB than NotSupported because there would never be a caller transaction, just like the way RequiresNew is a better fit than Required. But still, the spec designers choose to go with Required and NotSupported rather than RequiresNew and Never. If somebody can throw some light on this, it would be great
Imagine a scenario where you want to invoke a MDB from a Session Bean's (say Stateless) method. The method does some transactional database updates and then puts a message on a queue to invoke the MDB. You want the database updates to be transactional but you always want the MDB to run in an unspecified transaction context.
If we use Never for the MDB then we can't achieve this because the SLSB method will always run in a transaction but trying to run the MDB within an existing transaction will always throw an exception. Therefore NotSupported makes more sense in this scenario because the transaction will be suspended in case there is one.
I would like to differ with you on this. Your argument gives the impression that the stateless session bean is the caller of the MDB. But that's not the case. The SLSB would just put the message in the queue and go ahead and complete the transaction. Its the JMS service that delivers the message right? The SLSB might even complete the method even before the message is delivered to the MDB. Do you mean to say that the SLSB's transaction would be suspended till the MDB processes the message and then resume later? Its not even asynchronous in that case and beats the whole purpose of MDB's There is no concept of "caller transaction" here. The SLSB is NOT the MDB's caller and hence the SLSB's transaction would not get suspended. I think it would have made no difference if MDB's had used Never.
That's exactly what I am trying to say, with MDBs you never have a caller hence you never have caller's transaction.
So with MDBs you never have to think about an existing transaction. You just tell the container whether you want your MDB to run in a transaction or not(using Required or NotSupported).
The contract for the transaction attribute Never says that run the onMessage method of the MDB without a transaction and if there is an existing transaction context throw exception back to the caller. So throwing the exception back to the caller (who is the caller of an MDB???) doesn't make sense.
Whereas NotSupported silently suspends an existing transaction if there is any. This behavior fits more to a MDB that's why spec designers would have thought it to be more appropriate.
Originally posted by B Sathish: But Never is simpler than NotSuppported right ???
Lets not forget that we are in an MDB here - there will never be a pre-existing transaction context. So in that regard Never and NotSupported will produce the same behaviour: the method will run in an "unspecified transaction context".
However when you compare Never and NotSupported in general Never is the more dangerous one because it could throw an exception (will never happen in an MDB) while NotSupported only suspends the transaction (will never happen in an MDB).
Furthermore in an MDB there is no-one to throw an exception to (not that Never would ever have the chance to throw one in an MDB).
So overall NotSupported is the "safer" one to convey "runs in an unspecified transaction context".