9 Replies Latest reply on Jan 8, 2004 4:03 AM by Greg

    transaction boundaries and JMS

    Greg Newbie

      All,

      I'm having trouble with transaction boundaries with JMS , and the JBoss Entity bean cache getting out of sync with the DB.

      I have an application that primarily uses BMP Entity beans. I also have a scheduler service hooked up to fire off various JMS messages at certain intervals. When these 2 approaches try to update the same BMP Entity Bean, the JBoss cache seems to get out of date with the database.

      The BMP Entity bean that i'm altering in this case represents a configuration item that a user may or may not have -- so it makes sense that the same data could be inserted or removed numerous times which would correspond to the user enabling or disabling that config item. Each bean has a compound key made up of the user's id and the configuration type id, e.g. 2-4 might mean that user 2 has config item 4 enabled.

      Here's the MBean initiated sequence...

      (1)

      An MBean (via jboss scheduler) sends a message to a Message Driven Bean (via a Queue) which calls a Stateless Session Bean (using CMT) which tries to update a BMP Entity Bean.

      (2)

      This is ok at this stage, until I go back into my main web application and ejbRemove then ejbCreate the same BMP Entity Bean described above in (1)

      (3)

      When I do a findByPrimaryKey on the BMP Entity bean created above in (2), it has the same values as it did when it existed in (1), not (2) as I would expect. (what the!?)

      The only (impractical) way I've found to fix it is open the jmx-console and press the flushCache MBean Operation for the particular Entity bean being edited. Of course this then lets JBoss reload state from the db and everything is ok.


      Thanks very much,
      Greg.


      --------------------

      Adrian, I've read the FAQ but it doesn't help. In particular, maybe this could be elaborated on slightly....

      Question:

      I am sending/publishing to a queue/topic in an EJB but it does not commit/rollback
      when the EJB/JTA Transaction commit/rollsback.

      Answer:

      Use the JMS resource adapter connection factory bound at java:/JmsXA

      Define "use". I'd be interested to see a good explanation on how to string together a series of MDB -> SLSB -> Entity bean calls wrapped in a single transaction.

        • 1. Re: transaction boundaries and JMS
          Greg Newbie

          ...more info...

          (sorry, this is complicated to explain).

          in (3) when I talk about doing an ejbCreate, and then doing a findByPrimaryKey straight away and getting an old copy of the bean back (not the one I just ejbCreate'd), I mean that the non-primary key columns are different.

          I didn't mention in my main post that the bean has 4 columns, 2 of which are part of the primary key.

          Another way to show this problem is.

          1. Insert record using main web app with values {2, 4, null, null }
          2. Update same record via JMS -> SLSB -> BMP Entity bean so it now has values {2, 4, X, Y }.
          3. Remove the same record using main web app.
          4. Recreate the same record (again) with values {2, 4, null, null }
          5. Do a findByPrimaryKey for record with key {2,4}. The record I get back has values {2, 4, X, Y}, not {2, 4, null, null} and this is the problem.


          Thanks,
          Greg.

          • 2. Re: transaction boundaries and JMS
            Raja Master

            Are you doing a ejbremove to remove the bean? If you are otherwise doing the delete, then the commit-option maybe the culprit here as the default commit-option of A would not synch with the database. (Commit optoin A assumes the container is the only one handling the database). Can you try changing the commit-option to B so that the container synchs with the database at the beginning of each transaction?

            Regarding the XA, the one that Adrian mentioned is for clients where you have a sender from a client and a database update happening in the same Tx. For MDB-BMP combination, its based on the Tx level specified in the ejb-jar.xml. If your MDB has a Tx level of Required and the BMP also required, the BMP would execute in the same Tx started by MDB. If you need to rollback , use the ctx.setRollbackOnly to do the rollback for the DB.

            • 3. Re: transaction boundaries and JMS
              Greg Newbie

              yes -- using ejbRemove -- see my ejbRemove notes in my first post.

              I need to use commit option A, not B. I will try this to see what happens but it's not really a solution.

              Anyone have any ideas why I can do an ejbCreate with one set of values, and then do an ejbFindByPrimary key on that record and get old values back?

              i.e. this....

              1. Insert record using main web app with values {2, 4, null, null }
              2. Update same record via JMS -> SLSB -> BMP Entity bean so it now has values {2, 4, X, Y }.
              3. Remove the same record using main web app.
              4. Recreate the same record (again) with values {2, 4, null, null }
              5. Do a findByPrimaryKey for record with key {2,4}. The record I get back has values {2, 4, X, Y}, not {2, 4, null, null} and this is the problem.

              • 4. Re: transaction boundaries and JMS
                Adrian Brock Master

                Post a simple example that reproduces the problem.
                Most likely it is an error in your entity bean.

                Regards,
                Adrian

                • 5. Re: transaction boundaries and JMS
                  Greg Newbie

                  I think the example may need to be a small .ear file, as there would be too many files to post as raw text in this forum.

                  Adrian, can I post an .ear file directly to you? or is there some way to upload files to this forum?

                  • 6. Re: transaction boundaries and JMS
                    Adrian Brock Master

                    Send it to me, but I'm more interested in the code of your entity bean

                    Regards,
                    Adrian

                    • 7. Re: transaction boundaries and JMS
                      Greg Newbie

                      I've built a sample app to try to reproduce the error, but the damn sample app works perfectly, i.e. ejb cache remains perfectly in sync with db.

                      I get this on my main app...

                      18:56:47,578 WARN [TxConnectionManager] Prepare called on a local tx. Use of local transactions on a jta transaction with more than one branch may result in inconsistent data in some cases of failure.

                      ...when I sent a JMS message to it, but I do not get this message in my sample app.

                      Would you think the above warning message is related? If so, any ideas on what might be causing it?

                      Thanks,
                      Greg.



                      • 8. Re: transaction boundaries and JMS
                        Adrian Brock Master

                        I've added your question to the FAQ.

                        I doubt this is the cause of your problem.
                        If the commit failed, the entity would be invalidated in the cache.

                        Regards,
                        Adrian

                        • 9. Re: transaction boundaries and JMS
                          Greg Newbie

                          Found it. My stupid fault.

                          Problem was in the PK class for my Entity bean.

                          Basically, the cached hashCode for my PK class could get out of sync under some conditions which would no doubt screw up the entity cache.

                          It had nothing to do with JMS/MDB/SLSB/transaction boundaries. The symptoms of the problem only seemed to show up after the MDB/SLSB code had been called, which is why I posted here.

                          Thanks very much for your help.

                          Regards,
                          Greg.