Search code examples
multithreadingjakarta-eewebspherejtamessage-driven-bean

MDB with container managed transaction & worker thread


I have an MDB which uses container managed transaction (my container is IBM Websphere 7).

Websphere is using a global (JTA) transaction.

If my MDB thread starts a worker thread, and that thread begins a transaction, will that new thread be within the same transaction as the MDB?

I want the MDB thread to commit its transaction and acknowledge the MQ message as soon as my worker thread is successfully started. I do not want my MDB to rollback if the worker thread rolls back.

Edit: The code in the thread has this - it is not using annotations:

    txn = (UserTransaction)ctx.lookup("java:comp/UserTransaction");
    txn.begin();

So if look at txn.getStatus() it will be something other than STATUS_NO_TRANSACTION. Therefore I need to get the transaction manager appropriate for Websphere 7 and call "suspend()" before the txn.begin()? Is the correct approach to prevent problems?


Solution

  • Put the code which should not be in the same transaction as the onMessage() method into a separate method and set the transaction attribute for that method to REQUIRES_NEW. This will create a new transaction when the method is called and the success or failure of this new transaction won't affect the preexisting one.

    By the way, you aren't supposed to do explicit thread management in JavaEE applications.

    From the EJB 3.0 spec:

    The enterprise bean must not attempt to manage threads. The enterprise bean must not attempt to start, stop, suspend, or resume a thread, or to change a thread’s priority or name. The enterprise bean must not attempt to manage thread groups.

    You could look at using the timer service to effectively create a separate thread while leaving thread management to the server.