This week's giveaway is in the EJB and other Java EE Technologies forum. We're giving away four copies of EJB 3 in Action and have Debu Panda, Reza Rahman, Ryan Cuprak, and Michael Remijan on-line! See this thread for details.
If my application has to talk to another application using HTTP calls, and yet another application using XML-RPC/HTTP, how can i guarantee Transactions ? I don't think (distributed) Transcation can be guaranteed in such a J2EE Application. I wonder what the gurus here, think about is ?
Well, I do not call my self a guru... You can solve the problem by tunnelling your request through some facade. Stateless Session Bean is a nice candidate for this. So, you talk to your HTTP app (or web service, it doesn't matter) in one of its business methods. If, say, a network error takes place, an exception is thrown. In your business method you catch this exception and either: 1. Rollback the transaction and die quietly (EJBContext.setRollbackOnly()) 2. Make a lot of noise by throwing a system (runtime) exception and force the container to do the rollback. 3. Throw the app exception to the caller and the caller will decide what to do with a transaction.
If you mean to rollback the transaction (perhaps, even XA transaction) on a remote host after remote service finished without any errors, then you are talking about nested transactions. This is a very complicated topic and currently it is not supported by the EJB spec.
You can solve the problem by tunnelling your request through some facade. Stateless Session Bean is a nice candidate for this. So, you talk to your HTTP app (or web service, it doesn't matter) in one of its business methods.
So, let's supose that the bean in question calls a helper class - an ordinary java class. What exactly does happen there - if the helper throws that error - it will propagate to the bean and cause the transaction be rolled back, right? and everything is fine this way? Except if the network error occurs after a succesfull update on the remote machine(as u mentioned). One could implement a failsafe method, to try and check the remote system datastore(or query the system) for success after such a failure - is this some good? Any literature about this particular subject? Rudi PS: i'm not affraid to show this title: student ;-) and SCJP, SCEA I [ May 23, 2003: Message edited by: Rudi Vaum ]
Joined: Aug 21, 2002
So, let's supose that the bean in question calls a helper class - an ordinary java class. What exactly does happen there - if the helper throws that error - it will propagate to the bean and cause the transaction be rolled back, right? and everything is fine this way?
Yes, right. Transaction is bound to a thread of execution. So, whatever helper classes the bean calls, it is all executed in the same one transaction. Your responsibility is to catch this exception in the bean and act accordingly.
One could implement a failsafe method, to try and check the remote system datastore for success after such a failure - is this some good?
I can say by doing this you are trying to perform as a 'home-grown' TPM (Transaction Processing Monitor). Well, that's what is done usually behind the scenes for you, but not in this case, though Of course, if it is quite easy and occurs once or twice in your app - why not do it? (K.I.S.S. principle) It's not a solution otherwise. I don't know the domain of your problem, such solutions are very app-specific. I came across some solutions that utilised JMS for invalidating the results of transaction even. Whatever the problem is, I suppose, looking into nested transactions might help (Google anyone?). I'm not an author of the book (yet ), but I hope I'm of some help to you. cheers!
Joined: Apr 27, 2003
Andrew> I understood what you are saying here. But you know to reliably support transactions every participating module/api should support JTA(Java Transaction API) as per J2EE. I wonder how other people explain/handle this part while documenting...
The real problem occurs not when an exception happens while in HTTP call, and then the calling function receives some sort of an exception and rolls back the transaction. The real problem occurs when the HTTP call has finished executing and committed it�s changes to the data-store and then the transaction is rolled back by the client who called the HTTP method to start with. Without XA there is no way to work around this problem. Here are two scenarious: EJB A, calls HTTP, error occurs inside of HTTP call, returned to EJB A, EJB A rolls back TX, all is fine and everyone is happy. EJB A, calls HTTP, HTTP call completes and returns success to EBJ A, EJB A proceeds to execute other functions, and then receives a fatal exception, EJB A attempts to roll-back TX, TX rolls back for EJB A and it�s clients, but changes which have been persisted by the HTTP call are not rolled back. I don�t think there is a way to reliably implement 2 phase transactions between components which are not participating with the Transaction Manager. -AP_ http://www.myprofiles.com/member/profile/apara_business
Originally posted by Pamir Bahret: I think the answer for problem two is compensating transactions. What do you think ?
I was about to respond with Compensating transactions myself. scenario: transaction steps: 1. request credit card payment authorizaton. 2. complete some ordering operations, like stock transfer, etc. 3. issue confirmation to customer. Support step 2 or 3 fail. Ouch! As he said before the problem is how to rollback through step 1. Perform some kind of compensating transaction. Now I'm just thinking out loud: Either start a credit-back-to-card transaction in a separate thread, or queue it. Simple enough?
Juan Rolando Prieur-Reza, M.S., LSSBB, SCEA, SCBCD, SCWCD, SCJP/1.6, IBM OOAD, SCSA