6 Replies Latest reply on Mar 31, 2008 5:27 AM by Adrian Brock

    Stateless EJB calling WorkManager directly - legal?

    Gary Snider Newbie

      If a stateless EJB gets a JBossWorkManager (see code below) without going through an RA, should everything still work?

      The problem I'm seeing is:
      1) A CMT transaction TX1 is created in the EJB via hibernate call.
      2) the ejb schedules work in the WorkManager [workManager.scheduleWork(myWork, WorkManager.INDEFINITE, new ExecutionContext(), myListener); ]
      3) A new transaction is created TX2 by the WorkManager
      4) TX2 cannot 'see' any of the changes from TX1 either from inserts, updates and even after calling flush on the Hibernate session

      How can I coordinate these transactions? Do I need an RA?

      ------------------------------------------
      Config: 4.2.2.GA on MySQL 5.x
      XA-DataSource using MySQL xa driver

      EJB getting a JBossWorkManager:

      MBeanServerConnection mconn = (MBeanServerConnection) ctx.lookup("jmx/invoker/RMIAdaptor");
      ObjectName objectName = new ObjectName("jboss.jca:service=WorkManager");
      JBossWorkManagerMBean jwm = (JBossWorkManagerMBean) MBeanServerInvocationHandler.newProxyInstance(blah, objectName, JBossWorkManagerMBean.class,false);


        • 1. Re: Stateless EJB calling WorkManager directly - legal?
          Gary Snider Newbie

          Note about above:
          the call to WorkManager.scheduleWork takes an empty ExecutionContext. I've considered creating an ExecutionContext and setting the Xid to simulate transaction-importing. But I cannot for the life of me get the Xid of the first transaction (TX1 above).

          So if anyone has ideas there, I'm all ears. (but please address the original post as well as this one)

          • 2. Re: Stateless EJB calling WorkManager directly - legal?
            Vicky Kak Master

             

            "gsniderJBoss" wrote:
            If a stateless EJB gets a JBossWorkManager (see code below) without going through an RA, should everything still work?

            I am not able to understand why you are using the workmanager through the EJB , it should be used by the RA .
            It does not make any sense to me using the workmanager through the EJB .

            • 3. Re: Stateless EJB calling WorkManager directly - legal?
              Adrian Brock Master

               

              "vickyk" wrote:
              "gsniderJBoss" wrote:
              If a stateless EJB gets a JBossWorkManager (see code below) without going through an RA, should everything still work?

              I am not able to understand why you are using the workmanager through the EJB , it should be used by the RA .
              It does not make any sense to me using the workmanager through the EJB .


              What he is doing will work (assuming he's not breaking other ejb rules),
              but it's not very portable. :-)


              • 4. Re: Stateless EJB calling WorkManager directly - legal?
                Gary Snider Newbie

                Thanks, I assumed I would need to make these calls to an RA. But let's suppose I do that. Will that help my transaction issue?

                Will the RA be treated as a resource manager (for inclusion in XA)? In other words, will the following be true if I write and deploy an RA that makes the calls to WorkManager


                1) A CMT transaction TX1 is created in the EJB via hibernate call.
                2) the ejb uses the Resource Adapter to schedule work
                3) A new transaction is created TX2 by the WorkManager?
                4) TX2 will now participate in the XA transaction?


                Again a note: cmt transactions are used. I never 'have' programmatic access to TX1. I'm using the MySQL XA driver and have correctly setup the xa datasource.

                • 5. Re: Stateless EJB calling WorkManager directly - legal?
                  Vicky Kak Master

                   

                  "gsniderJBoss" wrote:
                  How can I coordinate these transactions? Do I need an RA?

                  Ok after looking at this post again and Adrian's response I think you should set the Xid on the ExecutionContext , this will not create new transaction TX2. Oh you have done this and I did not read this , my bad :(

                  Here is the code from older TM which basically imports the Transaction from XId supplied to ExecutionContext
                  public void registerWork(Work work, Xid xid, long timeout) throws WorkCompletedException
                   {
                   if (trace)
                   log.trace("registering work=" + work + " xid=" + xid + " timeout=" + timeout);
                   try
                   {
                   TransactionImpl tx = importExternalTransaction(xid, timeout);
                   tx.setWork(work);
                   }
                   catch (WorkCompletedException e)
                   {
                   throw e;
                   }
                   catch (Throwable t)
                   {
                   WorkCompletedException e = new WorkCompletedException("Error registering work", t);
                   e.setErrorCode(WorkException.TX_RECREATE_FAILED);
                   throw e;
                   }
                   if (trace)
                   log.trace("registered work= " + work + " xid=" + xid + " timeout=" + timeout);
                   }

                  http://anonsvn.jboss.org/repos/jbossas/branches/Branch_4_2/transaction/src/main/org/jboss/tm/TxManager.java
                  And this should also be handled in new TM(JbossTS) .

                  I need to see how to get the Xid , this is what will not be portable across the AS's .

                  "gsniderJBoss" wrote:
                  But I cannot for the life of me get the Xid of the first transaction (TX1 above).

                  I think you should do this
                  1) Get the TransactionManger from jndi .
                  2) Call getTransaction() on [1]
                  3) This Transaction obtained from [2] should be able to give you the Xid , I can see the older TM having getXid() method.
                  http://anonsvn.jboss.org/repos/jbossas/branches/Branch_4_2/transaction/src/main/org/jboss/tm/TransactionImpl.java

                  I need to find out how this can be done with Arjuna as 4.2.2 will have it , I will look at it . If you want to know about this quicker go to the Transaction forums Or dig code yourself if you are not lazy :)



                  • 6. Re: Stateless EJB calling WorkManager directly - legal?
                    Adrian Brock Master

                     

                    "gsniderJBoss" wrote:


                    1) A CMT transaction TX1 is created in the EJB via hibernate call.
                    2) the ejb uses the Resource Adapter to schedule work
                    3) A new transaction is created TX2 by the WorkManager?
                    4) TX2 will now participate in the XA transaction?



                    I think you've got some misunderstandings of how this works?


                    3) A new transaction is created TX2 by the WorkManager?


                    No, the WorkManager doesn't create transactions. It lets you specify
                    which existing external transactions the work should run under.


                    4) TX2 will now participate in the XA transaction?


                    Transactions are not partipants of XA (I thiink you mean JTA?) transactions.
                    XAResources are.

                    I think what you are asking for is that TX1 and TX2 are really the same
                    transaction running on different threads so the hibernate and asynch work
                    are committed together?

                    This breaks the EJB rules (see my comment above), unless you know
                    what you are doing. i.e. you make the ejb that submitted the work
                    wait for the work to finish and do the thread transaction association yourself

                    * no portable api to get the transaction manager to do this
                    * you can break things big time if you mess this up

                    NOTE: Spec support for this feature may be available in JavaEE6?
                    assuming the JSR 237 people ever finish the spec:
                    http://www.jcp.org/en/jsr/detail?id=237 and the JavaEE committee accepts it.