Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Stateful Session Bean Discard

 
Juggy Obhi
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Whenever any runtime exception occurs in an EJB, the bean is Discarded by the container. The bean is no longer referenced and becomes candidate for the removal by GC.

In case the bean is Stateless Session Bean OR Message Driven Bean both of which do not maintain any state,the task is straight forward and result in hardly any problem to the client.

I have a doubt regarding Stateful Session Bean Discard operation. Say we have performed 3 operation on the SFSB, Method1, Method2 and Method3. Method 3 results in a Runtime Exception. If now the bean is discarded, the effects caused by method1 and method2 will go in vain. How do container manage this. Is this true that client will have to perform method1 and method2 again?? Please guide.
[ September 25, 2008: Message edited by: Juggy Obhi ]
 
Sergio Tridente
Ranch Hand
Posts: 329
Java Linux Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It method1, method2 and method3 share the same transaction (e.g.: extended transaction or same inherited transaction from client), then the Container rollbacks the transaction. It always discards the stateful session bean instance. Rolling back the transaction serves to avoid inconsistent state in the database and discarding the EJB instance serves to avoid inconsistent state in the bean instance.
 
Juggy Obhi
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Sergio, Thanks for coming to this post as well. I needed help on this too.

What you have said is perfectly correct. The Transaction must Roll Back and Bean Should be Discarded so that others do not get infected with the inconsistent state of the Stateful Bean.

The doubt i am having is if method1, method2 and method3 executes with 3 independent Transactions and only method 3 results in Runtime Exception. If we are discarding the bean we are discarding the effects caused by method1 and method2 as well. Ideally only effects caused by method3 should get rolled back.

I want to know what container do about it. Whether a new bean is born(and method1 & method2 needs to be performed again...and i don't think its good) or Container retains a copy of that discarded bean (with effects from method1 and method2 only)
 
Satya Maheshwari
Ranch Hand
Posts: 368
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The doubt i am having is if method1, method2 and method3 executes with 3 independent Transactions and only method 3 results in Runtime Exception. If we are discarding the bean we are discarding the effects caused by method1 and method2 as well. Ideally only effects caused by method3 should get rolled back.


If method1,2 and 3 perform a task that are related, they should do so in the same transaction, so that its commit all or nothing. And if these 3 methods are doing independent unrelated things, they can do it in their own individual transactions and commit, though a stateless session bean should be used in such a case. Committing to the database is tied up to the transaction, so if you have independent transaction per method, its commited as soon as the method completes and can't be rolled back if some other method throws an exception unless its in the same transaction.
 
Juggy Obhi
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Satya,

Consider we have a "int counter=0" in a stateful session bean. We have three methods method1(), method2() and method3() each responsible for adding 5 to it.

I understand your point and its perfectly logical to have stateless session bean for this And the fact which you said really very well that if they are related they should belong to the same transation.

But just for next 5 mins consider the above scenario. If method1 update the counter to 5, method2 update the counter to 10, method3 a Runtime Exception. If you are discarding the bean you are resetting the counter to 0 (a new Bean) which ideally should be 10 as runtme exception occured in method3 only. So what exactly happens?
 
Sergio Tridente
Ranch Hand
Posts: 329
Java Linux Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Juggy,

Let's go slowler...

1) You get a reference to stateful session bean (either thru DI or JNDI lookup)
2) You call method1(), which starts a new transaction (T1), adds one row to the database and sets the counter instance variable to 5 (here counter represents some conversational state of your stateful session bean). When the method retuns, transaction T1 is commited.
3) You call method2(), which starts a new transaction (T2), updates the row in the database and then sets counter to 10. When method2() returns transaction T2 is commited.
Up to this point, you have inserted and updated one row in the database (these changes are already commited and won't rollback) and conversational state variable counter equals 10.
4) You now call method3(), which starts its own transaction (T3), and updates again the same row in the database. But it throws now a system exception (RuntimeException). Transaction T3 is rolled back (the changes you made in the database inside this transaction are lost) and the bean instance is discarded. This implies that you cannot access its conversational state anymore, which is irremediably lost.
5) From now on, if you try to use the reference you got on step 1) you'll get a javax.ejb.NoSuchEJBException.
If you need to call method1(), method2() and/or method3(), you'll need to get a new reference to the stateful session bean: you'll get a reference to a new instance, so instance variable counter (its conversational state) will be set to 0.

I hope this makes it a little clearer.
[ September 27, 2008: Message edited by: Sergio Tridente ]
 
Juggy Obhi
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

you'll get a reference to a new instance, so instance variable counter (its conversational state) will be set to 0.


This truth is actually bugging me. I believe that when you regain the reference (to the new bean), Container should be intelligent enough to return you a bean with counter=10 and Tx1 and Tx2 performed in method1 and method2 respectively committed in the database. In other words a bean exactly similar to the original bean right before method3().

But what is happening is that you are returned a new bean with Tx1 and Tx2 committed but counter=0.
 
Sergio Tridente
Ranch Hand
Posts: 329
Java Linux Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Juggy Obhi:
I believe that when you regain the reference (to the new bean), Container should be intelligent enough to return you a bean with counter=10 and Tx1 and Tx2 performed in method1 and method2 respectively committed in the database. In other words a bean exactly similar to the original bean right before method3().


How would the Container achieve that? The only way I can think of would be by serializing the bean's state before a transaction begins and by restoring the serialized state in the event of a transaction rollback. Too complicated and not really practical.

I think the problem in the scenario you describe is in your application design. If the bean's conversational state is so closed related to database commits, then it should be using an extended persistence context that would expland for the life of your stateful bean.
 
Juggy Obhi
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well Said Sergio ! This answered my query . I will give you 2% from my score Thanks
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic