aspose file tools*
The moose likes EJB and other Java EE Technologies and the fly likes Creating threads in EJB Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » EJB and other Java EE Technologies
Bookmark "Creating threads in EJB" Watch "Creating threads in EJB" New topic
Author

Creating threads in EJB

Dave Teare
Ranch Hand

Joined: Oct 09, 2002
Posts: 80
Okay, I am sure this is a hot topic and am prepared for a religious argment!
I want to create a Thread inside of my session bean, but the specification says I am not allowed. I understand that the spec is "trying to help developers" by allowing them not to worry about threading issues (something that I think is unreasonable - it's like saying you shouldn't have to understand instance variables are not thread safe in servlets - it's something you simply have to know).
Anyway, I would like to know what terrible things will happen to me if I create a new thread inside my bean - will the world come to an end? Will WebSphere slap my hand? Or will everything be fine except that I broke a rule?
I simply want to call a service that will asyncronously call a third party to validate a credit card number. While this is happening, I would like to get a DB transaction ready to commit. If the CC# is valid, I commit the TX; if not, I rollback and notify the user of the failure. If everything is fine, I would also like to send an email with javamail - but that is multithreaded too....
Can I do this safely? Any consequences?
Thanks!
--Dave.
Kyle Brown
author
Ranch Hand

Joined: Aug 10, 2001
Posts: 3892
    
    5
Why is this asynchronous if you want to do it all in a single transaction? What makes the validation asynchronous? The description just doesn't make sense.
And yes, if you spin off a thread WebSphere WILL slap your hand. You can't work with WebSphere transactions in your own threads... However, given the problem description I'm still not sure why you need the second thread...
Kyle


Kyle Brown, Author of Persistence in the Enterprise and Enterprise Java Programming with IBM Websphere, 2nd Edition
See my homepage at http://www.kyle-brown.com/ for other WebSphere information.
C Chavan
Greenhorn

Joined: Mar 19, 2004
Posts: 27
having asynchronous call within synchronous txn operation seems really bad idea but if there is no other way to do it then you may consider introducing a mediator to make it pseudo-synchronous.
The mediator is something like a database table that may have an Id field, a status field and CC response fields. Whenever a message is sent asynchronously to CC validation (assuming JMS), just before sending the message, a row is inserted in the table with status = "waiting" and a new Id (PKey) will be returned. this id is then passed in JMS message header (JMS correlation id). After this is done, the code keeps reading the DB row until status becomes "completed"
While the above bean is waiting to see the completed status, when a response is received back, the MDB listening to the CC response queue will update the table row (whose id in JMS message header) with status = "completed" and response values e.g. CC confirmation number etc.
After status changes to completed, the main bean will proceed with other txn commits and sending response back to client.


SCJP, SCWCD, SCBCD, SCEA
Dave Teare
Ranch Hand

Joined: Oct 09, 2002
Posts: 80
Hi Kyle,
Thanks for your response. Essentially I have a 3rd party web service that I need to call to validate the CC number. The QoS agreement states ~3 second response. I also have some business logic that needs to be performed which prepares a Unit of Work; this takes ~3 seconds. I want to run these in parallel s.t. it takes 3 seconds instead of 6.
What I was thinking was to fork off a thread that will call the web service at the beginning of my Session Bean, perform my work, and then join the CC validation thread. If the CC was not valid, I would setRollbackOnly, and throw my application exception. If the CC was valid, I would store the confirmation number into my UoW and then exit normally. CMT would then commit my UoW.
With this approach, I don't mind that my CC thread doesn't have a transaction since I don't plan on using it. I just don't like disobeying the spec, even though I might not agree with it.
I've thought about MDB's, but sending messages to a queue is part of the transaction. The message won't be sent until I commit.
Any thoughts?
Thanks!
--Dave.
Dave Teare
Ranch Hand

Joined: Oct 09, 2002
Posts: 80
Thanks for the response C Chavan, this is an interesting idea.
A few thoughts / issues I have:
1. You mention calling the CC validator via JMS, is this different than using a MDB? I assume they are identical since MDB piggybacks on JMS. I ask because in the EJB 2.0 spec it says that messages are not delivered until you commit your transaction. I am currently using CMT, which will not work for what you describe (at least not in a single bean).
2. How would I poll the DB row waiting until it changes to "completed"? I assume I read it, if it is in state "waiting", I do a Thread.sleep(), right? Is this use of threads violating the EJB spec? If I remember correctly, it says you can't create threads, but maybe I can use static methods on them. :roll:
Assuming I wanted to keep CMT, I guess I would end up looking something like this:

Is this what you were expecting? I could also acheive this result from the action class with 2 remote calls, like this:

I'm not sure if I will do it this way, but it is definetly food for thought. I would rather spawn a thread to call the web service and join it before my Session Bean completes - as described in my response to Kyle. But this mediator is a neat idea....
Any thoughts?
Thanks!
--Dave.
[ March 20, 2004: Message edited by: Dave Teare ]
Vishwa Kumba
Ranch Hand

Joined: Aug 27, 2003
Posts: 1064
Not sure if you can use Thread.sleep either
Since U plan to call Web Services, I guess you are using EJB2.1.
Ajith had mentioned something about Timer Services
before
C Chavan
Greenhorn

Joined: Mar 19, 2004
Posts: 27
Dave,
As you described in your post, the operation can be done in 2 steps (methods) from action.
The scenario I described although feasible, might prove expensive as one has to poll the DB row. instead of thread.sleep(), one can do something like -
for (long i = 0; i < Long.MAX_VALUE; i++){
}
And yes, I mean MDB when i meant JMS. I was thinking of sending a message to a queue. this message will contain info that needs to be sent to CC validator service. A MDB listening to this queue will call the CC validator service on receiving a message and will update the DB row with status completed and with CC validation result.
But in my opinion, introducing JMS may complicate the situation more
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Creating threads in EJB