Creating new java threads in Message Driven Bean (MDB)

Is it possible to start / create a new java thread from MDB? I have a requirement to do some parallel processing from the code in the MDB, and then return control back to the MDB.

Requirement: A message arrives in MDB, then some code processing. Then two new subordinate threads are started, which do some parallel work. Prior to this, the MDB is waiting. when threads shut down. Then control returns to the MDB, which completes the associated final / cleanup operation.

Is it possible to start a new thread (Runnable) from MDB? If not, what should be the alternative?

+4
source share
4 answers

Starting new threads in MDB is bad practice. It will work, but new threads do not control the application container, so they can behave unpredictably. They can even ruin the flow control that the container is trying to support. Worse, if the application is deployed in a cluster, then user-defined threads will fail.

In your scenario: instead of starting new threads, create a new MDB with the flow logic (so it will now be controlled by the controller), and then send a message to this new MDB. If you want the control to return to the parent MDB, then I think use your parent MDB in the global transaction, so that the parent MDB waits for the MDB to complete and control returns.

+1
source

Bad idea if you are doing transactional work in threads.

The thread that is currently performing work in the transaction launched by the EJB container is associated with the transaction context. In your case, the onMessage method in the MDB initiates a new transaction (unless you specify a NotSupported handle), and the thread executing this transaction will be associated with the transaction context. Starting a new thread does not extend to the transaction context of the child thread. This will lead to the creation of a new transaction when the container discovers that the child thread is trying to access the transactional resource without a transaction context.

Although some (or most?) Operations managers support multiple threads that share the same transaction context, this may (and most likely will) not apply to threads initiated by the application.

+2
source

Starting a stream from the MDB violates the specification.

Enterprise JavaBeansTM, version 3.0, basic EJB contracts and requirements in section 21.1.2 Programming restrictions:

  • A bean should not use thread synchronization primitives to synchronize the execution of multiple instances.

  • A bean should not attempt to manage flows. A bean should not attempt to start, stop, pause or resume a stream or to change the priority or name of a stream. A bean should not attempt to manage thread groups.

+1
source

You basically miss the Java EE and MDB points.

The Java EE container is a managed runtime. The fundamental idea of ​​the Java EE container is that, by delegating certain orthogonal problems to the container, such as transaction management, the component is still focused on business logic and (in utopia) is a reusable component that does not accept the assumption about the runtime.

Before MDB, the Java EE container was a passive-reactive system that did not allow the coordination of asynchronous active agents on the container side. Message Driven Beans then addressed this by providing a standard way to trigger asynchronous server-side actions.

You have an original e0 event that is consumed by MBD0 . In message MDB0 e1 will be generated and a message will be sent in response to MBD1 , which will then do its job and send msg to MDB2 , etc.

There you have a simple workflow of n consecutive steps using pub / sub messaging semantics (and o / c with asynchronous semantics), and all involved threads are managed by the container. If you want the actors to work simultaneously and then collect the results and begin the final action, consider using templates related to JMS themes.

+1
source

All Articles