On Tue, 16 Jul 2002 19:22:54 +1000, Craig O'Shannessy <[EMAIL PROTECTED]> wrote:

>Hi,
>
>I wonder if someone could clear up a problem for me.  It seems that a
>Stateless session bean cannot really use a Stateful session bean for
>two reasons.

A Stateful Session Bean can indeed be called from a Stateless Session Bean.  Read on.

>1. The stateless bean cannot call remove on the stateful, therefore can't
>   clean it up (see code below)

You're right in that the Stateful Session Bean using Session Synchronization cannot be 
destroyed while it's still participating in a transaction, because then the bean would 
be destroyed before finding out the final results of the transaction it's listening 
to.  However, you can work around this problem by creating the Stateful Session Bean 
before the transaction starts, and destroying it after the transaction completes.  
You'd then pass that stateful session bean as a parameter to the stateless one.

For example, the user could call session bean A (which would have it's transaction 
attribute set to NOT_REQUIRED) which creates the Stateful Session Bean and then calls 
session bean B (with transaction attribute REQUIRED or REQUIRES_NEW) and passes as an 
argument a reference to the stateful bean.  When the call to session bean B returns, 
the stateful session bean is notified of the results of the transaction.  Bean A would 
then proceed to clean up the stateful bean.  Alternatively the client itself could 
perform the duties of Session Bean A by creating (and later destroying) the stateful 
session bean and then passing it as an argument to Session Bean B.

>2. If the stateless bean holds onto a reference to a stateful bean to get
>   around creating one on each call and avoid problem 1., another problem
>   occurs.  The Stateless bean can be shared between concurrent transactions
>   (see quote from spec below), therefore the stateful beans transactional
>   scope is indeterminate (cause nasty blocking or even overlapping
>   transactions?)

This actually very much depends on the design.  If the stateless session bean's 
transaction attributes are REQUIRES_NEW, then each call to the stateless bean would 
create a new transaction, which would complete IMMEDIATELY as the method calls return. 
 Since the stateless session bean is still single threaded, it would be impossible for 
the stateful session bean to be participating in two transactions at once.

Still, keeping this sort of conversational state as a field in your stateless session 
bean should be considered very bad design and avoided all together, even if that state 
were reinitialized on every call to the stateless bean.

So your design choices are either to adopt the design I mentioned earlier, or to 
instead wrap your non-transactional resource in a regular java object which implements 
the javax.transaction.Sychronization interface and gets registered as a listener to 
the Transaction.

>One reason you might want to use a Stateful bean from a Stateless is to
>do SessionSyncronization on a non transactional datasouce for example.

Keep in mind that just because your non-transactional resource is wrapped by a 
transactional session bean implementing session synchronization with the appropriate 
undo logic, this doesn't mean that your resource is truly transactional now.  There 
can be scenarios where your undo code might fail (such as the resource going offline), 
and your stuck with a datastore in a non-deterministic state.  Making a truly 
transactional resource requires implementing the Transaction_XA protocol and using a 
write ahead log, which ends up getting very, very complex.

In general, I've found very little practical use for the Stateful Session Bean which 
implements SesssionSynchronization.  It is my firm opinion that Stateful Session 
Beans, if used at all, should only be used to hold conversational state on behalf of 
the client (such as aggregating user input or sending the client a large result set in 
pages of 10 objects at a time).  This means Stateful Session Beans should be 
restricted to the layer of your application called directly from the client, and 
should NEVER be called by another enterprise java bean.

Doug

P.S.  I'm using the EJB-Interest web interface to send this e-mail, which does a poor 
job of poor line wrapping.  My apologizes.

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff EJB-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to