3

I need to fire off a long running batch type job, and by long we are talking about a job that can take a couple of hours. The ejb that has the logic to run this long running job will communicate to a NoSQL store and load data etc.

So, I am using JMS MDBs to do this asynchronously. However, as each job can potentially take up to an hour or more (lets assume 4 hours max), I dont want the onMessage() method in the MDB to be waiting for so long. So I was thinking of firing off an asynchronous ejb within the onMessage() MDB method so that the MDB can be returned to the pool right after the call to the batch ejb runner.

Does it make sense to combine an asynchrous ejb method call withing an MDB? Most samples suggest using 1 or the other to achieve the same thing.

If the ejb to be invoked from the MDB is not asynchrous then the MDB will be waiting for potentially long time.

Please advise.

Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
user983022
  • 979
  • 1
  • 18
  • 30

3 Answers3

3

I would simplify things: use @Schedule to invoke @Asynchronous and forget about JMS. One less thing that can go wrong.

Whilst not yet ready for prime time, JSR 352: Batch Applications looks very promising for this sort of stuff.

https://blogs.oracle.com/arungupta/entry/batch_applications_in_java_ee

Andre
  • 691
  • 3
  • 11
  • Hi Andre, your answer is relevant now since JSR 352 is now mature. However, it seems not possible to fire up a batch job from a JMS Message listener in this version `BatchRuntime.getJobOperator().start("job_id", new Properties())` The batch job gets stuck in STARTED status – kosgeinsky Jul 02 '17 at 15:53
1

It's a matter of taste I guess.

If you have a thread from the JMS pool running your job or if you have an async ejb do it, the end result will be the same - a thread will be blocked from some pool.

It is nothing wrong with spawning an async bean from a MDB, since you might want to have the jobs triggered by a messaging interface, but you might not want to block the thread pool. Also, consider that a transaction often time out by default way before an hour, so if you do MDB transactional by some reason, you might want to consider fire of that async ejb inside the onMessage.

Petter Nordlander
  • 22,053
  • 5
  • 50
  • 84
  • thanks Petter. So generally, am I correct in thinking that firing an async bean from with the onMessage (of an mdb) will prevent the mdb from being blocked from the pool? This is what I want, but you are right, the async ejb itself will block a thread anyway, but at least there is a messaging interface to launch the jobs. -- one other thing, the mdb wont be transactional. Should I set a time out flag in the async ejb thats invoked from the mdb or the mdb in this case? – user983022 Feb 01 '13 at 14:49
1

I think Petter answers most of the question. If you are only using mdb to get asynch behaviour, you could just fire the @Asynchronous asap.

But if you are interested in any of the other features your JMS implementation might offer in terms reliability, persistent queues, slow consumer policies, priority on jobs you should stick to mdb:s

One of the reasons behind introducing @Asynchronous in ejb 3.1 is to provide a more lightweight way to do asynchronous processing when the other JMS/MDB features are not needed.

Aksel Willgert
  • 11,367
  • 5
  • 53
  • 74
  • thanks Aksel. I was always under the impression that mdb being blocked for hours was a bad thing to do which is why I thought of the asynch ejb method invocation from within the mdb freeing it up straight away. Perhaps I'm incorrect here and can just let the mdb wait until the bulk load job is completed. Like you say I can make use of other mdb feature in this case. – user983022 Feb 01 '13 at 15:46