5 Replies Latest reply on May 23, 2007 3:25 PM by fastbob

    Asynchronous send to MDB

    fastbob Newbie

      I must be missing something. I setup a queue to a MDB under JBoss 4.0.1 default configuration and everything appears to be working correctly. Auto-acknowledge is turned on. However, when the message is sent, it seems to behave synchronously all the way from the send through executing the onMessage method of the MDB. In other words, the send for a non-transacted message waits for the MDB to complete processing before returning. The commit for a transacted message behaves similarly.

      Perhaps it's my ignorance of JMS, but I expected that at most the delivery of the message to the queue would be synchronous, not the MDB execution. The whole purpose of using JMS in this case was to delegate a long-running operation to the MDB so that the sender could continue without waiting for results. Is there something else I need to be doing? Thanks.


        • 1. Re: Asynchronous send to MDB
          fastbob Newbie

          I've now tried the same code under 4.0.4, with the same results. In addition, I've tried sending the request from a new thread. No joy.


          • 2. Re: Asynchronous send to MDB
            Adrian Brock Master

            No it does not. It goes through at least two different threads before delivery to the MDB
            1) A delivery thread the client side
            2) A thread pool in the MDB

            What you are probably seeing is an artifact of the OS scheduling of threads
            where the sending thread on the server is not being scheduled ahead of the MDB threads.
            I'll bet if you add a sleep() to the MDB you don't see this behaviour.

            • 3. Re: Asynchronous send to MDB
              fastbob Newbie

              It's possible thread scheduling is coming into play (runnining on WinXP), but I think some of my experiments indicate something else is having an effect.

              By way of background, the app uses CMP EJB 2 beans and is deployed under JBoss 4.0.4, UIL2, and JDK 1.6. UI is JSF/MyFaces and DB is MySQL 5.0.18. The queue is the default configuration queue A. The intent is to send messages from the UI thread to an analysis queue MDB without waiting for the results.

              Tried adding a sleep() as suggested to the MDB (there was already a yield() there). Still acted synchronous. Modified the sender to spawn a low priority thread to perform the send (I know, bad EJB practice). Still synch.

              Created a standalone sender from the JBoss examples sending to the app. Acted asynch - the sender posted the messages without waiting for the MDB to process them. Ran a standalone receiver with simulated load and app sending. Acted asynch, sender posted messages without waiting. Reverted to app sending and receiving. Still synch, with or without transacted messages.

              So it appears something is going on when the app UI thread is sending to the MDB. They are entirely separate thread groups (main vs. RMI Runtime), so it's not clear to me where the scheduling issue is arising. Might it have something to do with CMP? Something else? Thanks.


              • 4. Re: Asynchronous send to MDB
                Anil Kumar Newbie

                What I suggest is not to use threads at all...the behaviour what you are seeing is may be because of some logical/configuration issues.

                Anil Kumar

                • 5. Re: Asynchronous send to MDB
                  fastbob Newbie

                  Sorry, I didn't mean to give the impression that the application is using explicit threads (except for the experiments). The UI and MDB threads I referred to are automatically created by the EJB container.

                  I finally resolved the problem. Both the main code and the MDB were using CMP, and referring to the same EJB (although reconstituted separately, not passed). So as the main code tried to construct the web page, it blocked while accessing EJB's that might be in use by the MDB. In particular, I found the main code waiting in QueuedPessimisticEJBLock.waitForTx().

                  The solution was to change the MDB to bean-managed persistence, and only wrap actual updates (not reads) in a UserTransaction.