File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
The moose likes EJB and other Java EE Technologies and the fly likes EJB 2 Tx and Exception questions ? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login

Win a copy of Java Interview Guide this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Java » EJB and other Java EE Technologies
Bookmark "EJB 2 Tx and Exception questions ?" Watch "EJB 2 Tx and Exception questions ?" New topic

EJB 2 Tx and Exception questions ?

Jean-Luc Thirion

Joined: Jan 24, 2008
Posts: 19
Hi Ranchers,

i have a few questions about Exceptions and "Container Managed Transactions", note that I have a good idea about the answers but I hope precise and convincing answers. Thanks in Advance Ranchers!

1) An ApplicationException (CreateException, NotEnaughMoneyInAccount, FinderException...) thrown by a bean does not rollback the transaction , Why ? For instance, if the transaction was started by a stateless session bean "S" and if "S" throws an ApplicationException, why should I want to commit the transaction. Moreover, that means also that if a client of an entity bean receives a CreateException, the client has no idea if the database insert was successful. Too bad, isn't it ?

2) What is the need for setRollbackOnly if I want the running transaction to rollback ? Why not just throwing a SystemException (that will cause an automatic rollback) . Moreover, instead of relying on the other beans checking the "rollback only flag" with getRollbackOnly to avoid lenghty tasks, is throwing a SystemExcption not easier ? (OK! One argument against throwing a SysEx is that beans state may become corrupted, but an Entity Bean will resync with the DB at next method call, and a stateless bean will be reset, so this affects only Stateful beans ? Right ?)

3) When do I need SessionSynchronization and what would I want to put in afterBegin, beforeCompletion, afterCompletion (Tell me a use case please). Only Stateful session beans should need afterCompletion, in order to leave the bean in a clean state for the client when he calls the next method ?

4) Other question not about transactions but a general purpose question. With the "remote call procedure paradigm" i always have to get a "stub reference" to an object in order to call a method ? Is that not a performance problem?

I know my questions are a bit long.
Thank you if you read so far.

[ January 02, 2009: Message edited by: Jean-Luc Thirion ]
[ January 02, 2009: Message edited by: Jean-Luc Thirion ]
Raf Szczypiorski
Ranch Hand

Joined: Aug 21, 2008
Posts: 383
1. Application exceptions are propagated to the client, not wrapped in EJBException. The client may then react appropriately, maybe even retrying the failed operation. There may be no need to rollback the operations of a thousand of other distributed resource managers, if you can help it. Appliction exception are recoverable, contrary to system exceptions. Note. however, that you may request an Application exception to rollback the transaction - use ejb-jar.xml or @ApplicationException(rollback = true). The first case may be used when you don't control the code for the exception class (it comes from a library or sth).
2. You may not want to throw a system exception from a bean when you can help it. Generally, isn't it the basic rule that you shouldn't use exceptions for control flow? system exception should be what the name suggests - underlying system exception. When something is wrong with the business environment when this method is called, and you can test it, Application exception would be a better idea I think. Also, the bean would be destroyed (not so bad for a stateless bean, worse for a stateful bean, especially if it is injected, and you want to make use of it again - it's not there). I also read that setRollbackOnly() is used very rarely, mainly for the use case you told about - lengthy / expensive operations could check for the status before starting, so don't think of it much - you will know when you need it ;-)
3. SessionSynchronization allows you to kind-of initialize / clean your stateful bean at the transaction boundries. You may want to cache some data within the transaction, and have it initialized / cleaned in these methods, not do it yourself in your business methods to get cleaner code. Note it is only valid for stateful beans.
4. As far as I know, the stubs (in simple words) delegate the method calls you make to a remote object, using networking. You could probably do it yourself, but just think how much more complex you code would be if you needed to take care of the remote method call protocol yourself - initializing the network connection (possibly sockets), all these bytes and streams. Using it as it is now, with the stubs, the programmer gets the impression that a local object is used (if it hadn't been for the lookup, but dependency injection in case of EJB3 allows you to get rid of that sometimes). And as for performance - you use the interface, but the stub that implements it does everything you would have to do anyways. I don't see any performance impact here to be frank. If you mean that you always have to get a stub reference before every call, you have the options of caching the stub reference and just call its methods, you don't need to look it up all the time if you know that you will need it 10 lines of code later.

Note I am only learning this stuff, I am no guru.
Jean-Luc Thirion

Joined: Jan 24, 2008
Posts: 19
Thanks Raf for your detailed answers !

For point 4, aren't stubs a scalability problem ? For instance, imagine this situation:

If I:
1- get a stub linked to a stateless bean S in "EJB Server 1"
2- then Server 1 crashes and the balancer knows that,
3 - then I call a method on S.

Will i get an Exception, or can the method transparently be redirected to "EJB Server 2" ? I think it is possible if implementing the "EJB Object" and "Stub class" appropriately (so the vendor should care). But would that be compatible with the EJB spec ?

On example of what could be a server-vendor implementation that enables this behavior:

Stateless beans: To implement that we need first not to create a specific "EJB Object" for each client (because if we do that each subsequent requests on will have to be redirected to that specific EJBobject that lives on this specific server). So we need that the server creates - at startup time - one big "EJB Object for all stateless beans of type X" on each server. Then the returned stubs will need to have things like a "Client UUID, and the Virtual IP" .

Remote Entity beans: Same could be done as for entity beans. Each server has a big "one EJB Object for all beans of type X" , but the returned stubs have to know the primary key of the entity they are accessing, and the Virtual IP. For instance, if the client calls: entityAccount.setAmount(10); and that entityAccount has the pk #3000, the stub will send something equivalent to "call on VirualIPs EJBObject method entityAccoount.SetAmoun(#3000,10)", and each "big ejb object" on each server will know what to do: "take an entity bean, load it with Account #3000, ejbLoad, and then call method "setAmount(10) on the loaded bean"

Statefull bean: Not possible because the state of the bean lives on server1. So this will require complex "bean state" sync between the servers.

[ January 03, 2009: Message edited by: Jean-Luc Thirion ]

[ January 03, 2009: Message edited by: Jean-Luc Thirion ]

[ January 03, 2009: Message edited by: Jean-Luc Thirion ]
[ January 03, 2009: Message edited by: Jean-Luc Thirion ]
I agree. Here's the link:
subject: EJB 2 Tx and Exception questions ?
It's not a secret anymore!