9 Replies Latest reply on Jul 28, 2009 4:13 AM by jnusaira

    Tying JMS Queues to Transactions?

    jnusaira

      Was curious if there was something we were doing wrong here? or?


      But basically we have a Seam bean and it writes to the database then sends to a message queue.


      The problem being that it seems to send to the message queue before the transaction is committed. THe object we are sending to the message queue is an ID of a database object so it tries to retrieve that aned of course retrieves a null.


      Is there a way to tie these together?


      One guy here was going to make it a BMT and commit it before sending but that seems a bit sloppy. We ware using Seam 2.0.2 i believe .... not sure if higher v ersions resolved it?


        • 1. Re: Tying JMS Queues to Transactions?
          asookazian

          Are you using XA datasource?  Assuming you're using JTA so the tx mgr is managing two resources (one db and one JMS queue/session) so that qualifies as a distributed tx.


          Your scenario is similar to an amazon.com book purchase where the user navigates thru the wizard (shopping cart) for checkout and then purchases the book and gets the confirmation email.


          Well if the credit card portion of the transaction (or similar, like a db insert/update) fails for whatever reason, you don't want the email sent stating congrats! you just bought this great Seam book and now you're not going to get it! lol.


          You get my idea.


          So have you looked at 2PC/XA for this project?

          • 2. Re: Tying JMS Queues to Transactions?
            jnusaira

            Yes we are using XA datasources.


            According to one of our developers this is what he discovered



            Seam attempts to optimize creation and manage re-use of JMS components. Pre-creating a JMS Session and/or Sender outside the context of a transaction means that the components don't successfully participate in the JTA transaction. An attempt for force Seam to use an XA-complaint ConnectionFactory results in component life cycle errors because the component cannot be close at the end of the transaction.
            • 3. Re: Tying JMS Queues to Transactions?
              asookazian

              Sounds like implementation/design problem and/or possible bug (or lack of support?) in Seam/EJB3/JMS integration.  Post relevant code (including components.xml).  Have you looked at using @Asynchronous instead of JMS?


              Seam makes it very easy to perform work asynchronously from a web request. When most people
              think of asynchronicity in Java EE, they think of using JMS. This is certainly one way to approach
              the problem in Seam, and is the right way when you have strict and well-defined quality of service
              requirements. Seam makes it easy to send and receive JMS messages using Seam components.
              But for many use cases, JMS is overkill. Seam layers a simple asynchronous method and event
              facility over your choice of dispatchers:
              • java.util.concurrent.ScheduledThreadPoolExecutor (by default)
              • the EJB timer service (for EJB 3.0 environments)
              • Quartz



              There is an example in the Seam 2.1.2 distro (chatroom) that references the following:


              javax.jms.TopicPublisher


              javax.jms.TopicSession


              and an MDB:


              @MessageDriven(activationConfig={
                    @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Topic"),
                    @ActivationConfigProperty(propertyName="destination", propertyValue="topic/chatroomTopic")
                 })
              @Name("logger")
              public class LoggerBean implements MessageListener{...}



              But AFAIK it's not using XA datasource (nor are any of the other distro example apps).


              It would be nice if all the examples were configurable out-of-the-box for hsql db as well as mysql db.  The only example app that uses mysql is the wiki project.


              I'm interesting in knowing what the best practices solution is to this use-case/problem...

              • 4. Re: Tying JMS Queues to Transactions?
                jnusaira

                @Asynchronous doesnt work with SLSBs and wouldnt help us here anyways since we are putting about a million things in the queue.


                IMHO @Asynchronous is good when you are doing one offs like in a web request not when you are truly wanting to do batch work.


                I'll take another look at the chatroom problem, biggest problem is this problem isnt easily testable because it doesnt ALWAYS happen just under certain load conditions etc. I suppose i could put a thread wait in there to try and make it happen.

                • 5. Re: Tying JMS Queues to Transactions?
                  asookazian

                  You're talking about adding Thread.sleep(foo); in your method?  Not sure how that will simulate high load.  Perhaps try a load testing tool like The Grinder or JMeter.


                  This problem sounds like a pain in the ass, sorry.


                  Have you tried Seam 2.1.x or 2.2.x?  I'm not even sure if there are any JIRA that are related to your problem...


                  In any event, it seems to me that you should be able to use distributed tx's in your scenario (you would be able to do have done it in a J2EE 1.4 project, no?)


                  Post the stack trace at least....

                  • 6. Re: Tying JMS Queues to Transactions?
                    kapitanpetko

                    Asynchronous does work with SLSBs and is actually good for batch work as well. What are you trying to achieve?


                    Anyways, as to your problem, there are two possible solutions:



                    1. raise an event on transaction success (Cf. Events.raiseTransactionSuccessEvent) and send your message in a method that observes that event. This way you can be sure that the transaction is already committed.

                    2. do not use the Seam JMS components. Inject/get from JNDI the SessionFactory and do stuff the 'old fashioned way': get session, create sender, etc.



                    HTH




                    • 7. Re: Tying JMS Queues to Transactions?
                      jnusaira

                      Hmmm has Async ALWAYS worked on SLSB??


                      I remember trying it out back in december and kept running into issues that it wouldnt run in separate thread?? It would work fine on the POJOs just not on the SLSBs.


                      As far as your solutions .... i really like the first idea we use events for other stuff but never thought of using the raiseTransactinSuccessEvent ... thats actually a really good idea.

                      • 8. Re: Tying JMS Queues to Transactions?
                        kapitanpetko

                        Joseph Nusairat wrote on Jul 28, 2009 04:02:


                        Hmmm has Async ALWAYS worked on SLSB??

                        I remember trying it out back in december and kept running into issues that it wouldnt run in separate thread?? It would work fine on the POJOs just not on the SLSBs.



                        I don't know about always, but I am pretty sure it worked in December :) I was using Quartz, so that might make a difference. It is supposed to
                        work in a different thread regardless of the actual scheduler used.

                        • 9. Re: Tying JMS Queues to Transactions?
                          jnusaira

                          Nikolay Elenkov wrote on Jul 28, 2009 04:06:



                          Joseph Nusairat wrote on Jul 28, 2009 04:02:


                          Hmmm has Async ALWAYS worked on SLSB??

                          I remember trying it out back in december and kept running into issues that it wouldnt run in separate thread?? It would work fine on the POJOs just not on the SLSBs.



                          I don't know about always, but I am pretty sure it worked in December :) I was using Quartz, so that might make a difference. It is supposed to
                          work in a different thread regardless of the actual scheduler used.


                          Hmmm we used Quartz to.


                          Oh well no biggie i decided after I rather use a message queue because i didnt really want them to run more than 3 jobs at a time because if they ran more than that they could easily kill the memory of the server.