1 2 Previous Next 15 Replies Latest reply on Mar 26, 2008 6:34 AM by jhalliday

    AS4.2.2.GA + Hibernate + XADatasource 2 transactions not coo

    gsniderjboss

      See specs at bottom for app & db versions:

      I'm seeing the following in jboss/hibernate with CMT
      1) SLEJB using Hibernate: TransactionManager creates TX1
      2) Same EJB gets Xid from transaction and calls WorkManager with ExecutionContext.setXid()

      //import com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple
      //import com.arjuna.ats.jta.TransactionManager
      //import com.arjuna.ats.jta.xa.XidImple
      TransactionImple tx = (TransactionImple)TransactionManager.transactionManager().getTransaction();
      XidImple xidimple = new XidImple(tx.get_uid());
      ExecutionContext ctx2 = new ExecutionContext();
      ctx2.setXid(xid);
      workManager.scheduleWork(someObject, WorkManager.INDEFINITE, ctx2, listener);

      3) it's when calling WorkManager.scheduleWork that I get the exceptions below

      DEBUG [mycode] TX1 xidimple = a3291b1:da3:47e2d26a:58
      DEBUG [com.arjuna.ats.arjuna.logging.arjLogger] StateManager::StateManager( 2 )
      DEBUG [com.arjuna.ats.arjuna.logging.arjLogger] BasicAction::BasicAction()
      DEBUG [com.arjuna.ats.arjuna.logging.arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.BasicAction_10] - BasicAction::addAction () action a3291b1:da3:47e2d26a:58 adding a3291b1:da3:47e2d26a:62 Why is it adding one here? WorkManager acts like it didn't recognize that the Xid from TX1 was already passed in (a3291b1:da3:47e2d26a:58). Is there some special formatting I need from com.arjuna.ats.jta.xa.XidImple xidimple = new com.arjuna.ats.jta.xa.XidImple(tx.get_uid());?
      DEBUG [com.arjuna.ats.arjuna.logging.arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.BasicAction_11] - BasicAction::addChildAction () action a3291b1:da3:47e2d26a:58 adding a3291b1:da3:47e2d26a:62 result = true
      DEBUG [com.arjuna.ats.arjuna.logging.arjLogger] BasicAction::Begin() for action-id a3291b1:da3:47e2d26a:62
      DEBUG [com.arjuna.ats.arjuna.logging.arjLogger] BasicAction::actionInitialise() for action-id a3291b1:da3:47e2d26a:62
      DEBUG [com.arjuna.ats.arjuna.logging.arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.BasicAction_66] - Action a3291b1:da3:47e2d26a:62 with parent status 0
      DEBUG [com.arjuna.ats.arjuna.logging.arjLogger] ActionHierarchy::add(a3291b1:da3:47e2d26a:62, 1)
      DEBUG [com.arjuna.ats.jta.logging.logger] TransactionImple.getStatus
      DEBUG [com.arjuna.ats.jta.logging.logger] TransactionImple.registerSynchronization
      ERROR [STDERR] java.lang.IllegalStateException: [com.arjuna.ats.internal.jta.transaction.arjunacore.syncsnotallowed] [com.arjuna.ats.internal.jta.transaction.arjunacore.syncsnotallowed] Synchronizations are not allowed!
      ERROR [STDERR] at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.registerSynchronizationImple(TransactionImple.java:473)
      ERROR [STDERR] at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.registerSynchronization(TransactionImple.java:441)
      ERROR [STDERR] at com.arjuna.ats.internal.jbossatx.jta.jca.XATerminator.registerWork(XATerminator.java:138)
      ERROR [STDERR] at org.jboss.resource.work.JBossWorkManager.importWork(JBossWorkManager.java:187)
      ERROR [STDERR] at org.jboss.resource.work.JBossWorkManager.scheduleWork(JBossWorkManager.java:143)
      ERROR [STDERR] java.lang.IllegalStateException: [com.arjuna.ats.internal.jta.transaction.arjunacore.syncsnotallowed] [com.arjuna.ats.internal.jta.transaction.arjunacore.syncsnotallowed] Synchronizations are not allowed!
      


      I checked the code for com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple.registerSynchronizationImple
      It has a switch statement on the tx status. If it's not ActionStatus.ABORTED or ActionStatus.CREATED, it throws the error above (synchronizations are not allowed!). I checked the status of the tx right before the call and it is ActionStatus.RUNNING.

      Should this call still fail even though the TX is Running?
      ******************
      JBoss 4.2.2.GA (JBossTS 4.2.2 implied)
      MySQL XA Driver 5.1.5
      XA Datasource configured

        • 1. Re: AS4.2.2.GA + Hibernate + XADatasource 2 transactions not
          adinn

           


          I checked the code for com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple.registerSynchronizationImple
          It has a switch statement on the tx status. If it's not ActionStatus.ABORTED or ActionStatus.CREATED, it throws the error above (synchronizations are not allowed!). I checked the status of the tx right before the call and it is ActionStatus.RUNNING.

          Should this call still fail even though the TX is Running?


          Well, if the status is RUNNING and stays that way into the call then there are only two other possibilities. Since there is no info in the log to indicate that the TX has changed status (e.g. due to a timeout) I guess we have to look at those possibilities. Reading the code for twoPhaseCoordinator.addSynchronization (this class is the parent of AtomicAction which is the class of _theTransaction) the addSynch method will barf if the _theTransaction has a parent (this can't happen with JTA) or if the synchronization is NULL. So, I choose the last option :-) Maybe you could check this?

          • 2. Re: AS4.2.2.GA + Hibernate + XADatasource 2 transactions not
            jhalliday

            I have a suspicion the tx it's registering with is not the same one that's active on the Thread, it's the one created to run the Work. Which tx are you checking the status of and how?

            • 3. Re: AS4.2.2.GA + Hibernate + XADatasource 2 transactions not
              gsniderjboss

              adinn:

              ...the addSynch method will barf if the _theTransaction has a parent (this can't happen with JTA)...


              Actually debugging the TwoPhaseCoordinator.addSynchronization method, the following code is run:
              if (parent() != null)
               return AddOutcome.AR_REJECTED;

              So it looks like it does barf due to the parent. I can't speak to whether this can/can't happen with JTA


              jhalliday:
              Which tx are you checking the status of and how

              I get the Xid from the TransactionImple. I check this immediately after the Hibernate call and I'll get a value. e.g. abcd:efgh. That is way before any call to WorkManager. In other words, the Xid never changes and is generated after creation of TX1. The only time I see a new Xid is from BasicAction.addChildAction. e.g. mnop:qrst. To be honest, I don't know where that 'child' Xid/uid is coming from.
              //com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple
              //com.arjuna.ats.jta.TransactionManager
              //com.arjuna.ats.jta.xa.XidImple
              
              TransactionImple tx = (TransactionImple)TransactionManager.transactionManager().getTransaction();
              XidImple xidimple = new XidImple(tx.get_uid());
              ExecutionContext ctx = new ExecutionContext();
              ctx.setXid(xidimple);
              workManager.scheduleWork(myWork, WorkManager.INDEFINITE, ctx, listener);


              • 4. Re: AS4.2.2.GA + Hibernate + XADatasource 2 transactions not
                gsniderjboss

                Just some more info:

                It doesn't matter what datasource & driver I use. Either local-tx-datasource or xa-datasource with the respective driver (com.mysql.jdbc.Driver and com.mysql.jdbc.jdbc2.optional.MysqlXADataSource)

                Setting in jbossjta-properties.xml has no effect

                Creating an XidImple from the TransactionImple in either of these two ways has no effect: (the second one is for branching)
                1) XidImple xidimple = new XidImple(tx.get_uid());
                2) XidImple xidimple = new XidImple(tx.get_uid(),true);

                • 5. Re: AS4.2.2.GA + Hibernate + XADatasource 2 transactions not
                  jhalliday

                  In the normal course of things we don't allow nested transactions when running as a JTA implementation. i.e. you can't call begin() twice in a row on the same thread. However, some of the same sub-transaction handling mechanism is used to support transaction inflow in JCA connectors. Just out of curiosity, what happens if you suspend the transaction before calling scheduleWork, or use a different branch qualifier in the Xid?

                  • 6. Re: AS4.2.2.GA + Hibernate + XADatasource 2 transactions not
                    marklittle

                    Have you tried using the Xid from the existing transaction? Neither of the approaches you've mentioned for creating a XidImple will give you that.

                    • 7. Re: AS4.2.2.GA + Hibernate + XADatasource 2 transactions not
                      vickyk

                       

                      "mark.little@jboss.com" wrote:
                      Have you tried using the Xid from the existing transaction? Neither of the approaches you've mentioned for creating a XidImple will give you that.


                      I don't see the way to retrieve the Xid from the existing transaction , actually I asked user to come here for help
                      http://www.jboss.com/index.html?module=bb&op=viewtopic&t=131449




                      • 8. Re: AS4.2.2.GA + Hibernate + XADatasource 2 transactions not
                        vickyk

                         

                        /**
                         * If this is an imported transaction (via JCA) then this will be the Xid we
                         * are pretending to be. Otherwise, it will be null.
                         *
                         * @return null if we are a local transaction, a valid Xid if we have been
                         * imported.
                         */
                        
                         protected Xid baseXid()
                         {
                         return null;
                         }

                        Why is Xid to be null for the imported transaction via JCA ?
                        Do we have some test cases for JCA inflow transaction ?


                        • 9. Re: AS4.2.2.GA + Hibernate + XADatasource 2 transactions not
                          gsniderjboss

                           

                          "mark.little@jboss.com" wrote:
                          Have you tried using the Xid from the existing transaction? Neither of the approaches you've mentioned for creating a XidImple will give you that.


                          Actually if you know how to get the Xid from the existing transaction I would love to see that. As vickyk mentioned there isn't a clear way to do it. But through code inspection, the only thing that worked or at least was similar to arjuna code was:
                          TransactionImple tx = (TransactionImple)TransactionManager.transactionManager().getTransaction();
                          XidImple xidimple = new XidImple(tx.get_uid());


                          Also, I am trying to use transaction inflow based on suggestions from the JCA forum (set Xid on the ExecutionContext). This is my last hope. Otherwise I am having no success with TX1 and TX2 coordinating in my scenario (see original post). And I'm using 4.3.GA of JBossTS.

                          The only thing that works is to set the isolation level to read uncommitted. But that will not fly with my team.

                          • 10. Re: AS4.2.2.GA + Hibernate + XADatasource 2 transactions not
                            marklittle

                             

                            "vickyk" wrote:
                            /**
                             * If this is an imported transaction (via JCA) then this will be the Xid we
                             * are pretending to be. Otherwise, it will be null.
                             *
                             * @return null if we are a local transaction, a valid Xid if we have been
                             * imported.
                             */
                            
                             protected Xid baseXid()
                             {
                             return null;
                             }

                            Why is Xid to be null for the imported transaction via JCA ?
                            Do we have some test cases for JCA inflow transaction ?


                            Vicky, try checking all of the code first ;-) That's the base transaction and NOT the transaction type we create for imported transactions.

                            • 11. Re: AS4.2.2.GA + Hibernate + XADatasource 2 transactions not
                              marklittle

                               

                              "gsniderJBoss" wrote:
                              "mark.little@jboss.com" wrote:
                              Have you tried using the Xid from the existing transaction? Neither of the approaches you've mentioned for creating a XidImple will give you that.


                              Actually if you know how to get the Xid from the existing transaction I would love to see that. As vickyk mentioned there isn't a clear way to do it.


                              Have you been able to get the JCA TransactionImple created? If so, call baseXid and you'll get it.

                              • 12. Re: AS4.2.2.GA + Hibernate + XADatasource 2 transactions not
                                gsniderjboss

                                I'm actually not creating a JCA TransactionImple so I can't get the baseXid. I'm just accessing the current transaction from the TransactionManager

                                TransactionImple tx = (TransactionImple)TransactionManager.transactionManager().getTransaction();


                                • 13. Re: AS4.2.2.GA + Hibernate + XADatasource 2 transactions not
                                  vickyk

                                   

                                  "mark.little@jboss.com" wrote:

                                  Vicky, try checking all of the code first ;-) That's the base transaction and NOT the transaction type we create for imported transactions.

                                  Mark, actually I got confused with the comment however I was pretty sure that things would be okay as the product had been there for last 2 decades ;)

                                  Yes I can see that the new Transaction is getting created if the Xid propagated through JCA inflow does not exist .
                                  http://anonsvn.labs.jboss.com/labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/TxImporter.java



                                  • 14. Re: AS4.2.2.GA + Hibernate + XADatasource 2 transactions not
                                    gsniderjboss

                                    I've been debugging some more and I've simplified my problem. It then becomes a simple question of expected behavior:

                                    Environment: Stateless EJBs & Hibernate. Assume JTA 4.3.GA and AS 4.2.2.GA, MySql 5.0, XA driver and XA datasource. ALL EJB methods are TransactionAttribute=REQUIRED

                                    1) Stateless EJB creates a record (which creates TX1)
                                    2) Stateless EJB schedules Work for the WorkManager
                                    3) Work object calls another Stateless EJB to create more records (in TX2)

                                    Desired behavior: TX1 and TX2 can 'see' each others changes so that TX2 can create 'child' records based on data in TX1

                                    Actual behavior: TX2 is started in the WorkManager and cannot see TX1 changes. Also, even when passing TX1.Xid to WorkManager there is no coordination.

                                    What is the expected behavior?

                                    1 2 Previous Next