1 2 Previous Next 15 Replies Latest reply on Aug 31, 2012 5:50 AM by Rahul Agrawal

    Commit transaction after each service task?

    Richard Evans Newbie

      Hello there,

       

      JBPM 5.1 on Tomcat, persistence configured in Spring

       

      I have a number of processes, each with a series of service tasks punctuated by timers.

       

      I would like to persist process data after every service task to be confident that it is recoverable on catastrophic failure. I find, though, that data is committed only at timers and end of process. Is it possible to take control of transactions at a more granular level to get jbpm to commit more regularly?

       

       

      My config..

       

      <bean class="org.springframework.orm.jpa.JpaTransactionManager"

          id="transactionManager">

          <property name="entityManagerFactory" ref="entityManagerFactory" />

      </bean>

       

      <tx:annotation-driven mode="aspectj"

          transaction-manager="transactionManager" />

       

      <bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"

          id="entityManagerFactory">

          <property name="persistenceUnitName" value="persistenceUnit" />

          <property name="dataSource" ref="dataSource" />

      </bean>

       

      <bean class="org.springframework.orm.jpa.JpaTransactionManager"

          id="transactionManager">

          <property name="entityManagerFactory" ref="entityManagerFactory" />

      </bean>

       

      <drools:jpa-persistence>

          <drools:transaction-manager ref="transactionManager" />

          <drools:entity-manager-factory ref="entityManagerFactory" />  

      </drools:jpa-persistence>

       

       

      Thanks,

      Richard

        • 1. Re: Commit transaction after each service task?
          Mauricio Salatino Master

          Yes you can achive that if you use asynchronous tasks that introduces new wait states. Instead of having synchrnous tasks you can define your workitems to work asynchrnously and the safe states will cause the process to be persisted.

          Cheers

          • 2. Re: Commit transaction after each service task?
            Richard Evans Newbie

            That looks really promising, thanks, Mauricio.

             

            This is the sort of thing you mean?

             

            public void executeWorkItem(final WorkItem workItem, final WorkItemManager manager) {

                new Thread(new Runnable() {

               

                    public void run() {

                       

                       // Do it here           

                                   

                        manager.completeWorkItem(workItem.getId(), results);

                    }

               

                }).start();

            }

             

            I presume that in the new thread I'll have to re-instantiate the task in a new transaction based on it's id. Is that correct? I'm new to the jbpm api and am googling away for a good example but a steer would be most welcome if you can provide it!

             

            Thanks,

            Richard

            • 3. Re: Commit transaction after each service task?
              Rahul Agrawal Newbie

              Hi Richard,

               

              Are you able to continue with this strategy? Because I am also following the same strategy and had a lot of issues.

              Please look at the following thread.

               

              https://community.jboss.org/thread/204460

               

              The difference is I am using EJB instead of spring.

               

              @Mauricio:- Please have a look at it. Not sure where tha cause of the problem lies. Is it hibernate issue or jBPM one?

              • 4. Re: Commit transaction after each service task?
                Mauricio Salatino Master

                Hi Richard,

                No I didn't mean creating a new thread.. because if the JVM crash you will loose that thread.

                You SHOULD NOT DO THAT! (I'm not screaming with the capital letters.. it's just to emphazise it)

                 

                I was suggesting  something like:

                public void executeWorkItem(final WorkItem workItem, final WorkItemManager manager) {

                       

                                      

                     // SEND A Message to a QUEUE which will be processed by another component

                     // SEND THE WORKITEM ID AS PAYLOAD OF THE MESSAGE AND ALSO THE SESSION ID

                    // SO THE OTHER COMPONENT CAN RELOAD THE SESSION AND CONTINUE THE EXECUTION with        manager.completeWorkItem(workItem.getId(), results);

                    

                }

                 

                Cheers

                • 5. Re: Commit transaction after each service task?
                  Richard Evans Newbie

                  Hello Rahul. Yes, I did implement this strategy (or something very similar using a thread pool). I have often run into problems with the persistence context but have found everything works if I ensure there is no running transaction when I enter jbpm code.

                   

                   

                  In a common superclass of all handlers...

                   

                  @Override

                  public final void executeWorkItem(WorkItem workItem, WorkItemManager manager) {

                      WorkHandlerRunner task = new WorkHandlerRunner(kSession, workItem, this);

                      synchronized (threadPoolTaskExecutor) {

                          threadPoolTaskExecutor.execute(task);

                      }

                  }

                   

                   

                  In WorkHandlerRunner...

                  @Override

                  public void run() {

                      WorkItemManager manager = kSession.getWorkItemManager();

                      Map<String, Object> result = null;

                   

                   

                      try {

                          result = doRun(manager);

                      } catch (Exception e) {

                          ...

                      }

                      manager.completeWorkItem(workItem.getId(), result);

                  }

                   

                   

                  // Do my stuff and commit.

                  @Transactional

                  private Map<String, Object> doRun(WorkItemManager manager) throws Exception {

                      return handler.doExecuteWorkItem(workItem, manager);

                  }

                  • 6. Re: Commit transaction after each service task?
                    Rahul Agrawal Newbie

                    Hi Mauricio,

                    Thanks for the reply.

                     

                    This approach looks promising. But I do have a doubt regarding it. Do I need to load the session in the component which is processing the message? Can't I have the session stored at global level in JVM and use that? And for reloading do I have to dispose session in the executeWorkItem(...)? I am using strategy of using session-per-process. So there will be multiple process instances which will be using the same session, then is it a good idea to dispose it? Or even if i dont dispose it, is it good to reload it? Wont it cause problems?

                     

                    Thanks

                    • 7. Re: Commit transaction after each service task?
                      Rahul Agrawal Newbie

                      Dear Richard,

                      Thanks for the reply. Will try to implement it.

                       

                      I did not get

                      if I ensure there is no running transaction when I enter jbpm code.

                      what does this mean?

                       

                      manager.completeWorkItem(workItem.getId(), result);  will always require a transaction. And I am using EJB with CMT so transaction will always be associated with EJBs.

                      • 8. Re: Commit transaction after each service task?
                        Richard Evans Newbie

                        jbpm will manage its own transaction if there is not one running when its methods are called.

                        I have not used EJB CMT but I'd imagine that if you hand control to another thread there will be no transaction associated with it.

                        • 9. Re: Commit transaction after each service task?
                          Rahul Agrawal Newbie

                          You may be right. But I got an exception saying "No JTA transaction on joinTransaction call". Only when I explicitely started transaction using UserTransaction (and commited it), I got rid of that Exception.

                          • 10. Re: Commit transaction after each service task?
                            Rahul Agrawal Newbie

                            Are you able proceed with back-to-back service tasks?In my case this is where it is failing.

                            • 11. Re: Commit transaction after each service task?
                              Rahul Agrawal Newbie

                              One more update I would like to inform. If I have deployed my application, and then I am debugging it in eclipse using remote debugging then everything works fine but once i turn off eclipse remote debugging and run it normally then I am stuck at the same point. What could be the reason for this strange behaviour?

                              • 12. Re: Commit transaction after each service task?
                                Rahul Agrawal Newbie

                                I think single asynchrnous sevice task in the process works fine but in case of back-to-back service tasks that are executed asynchronously wont work if I start a new thread or even if I use JMS. Any opinion about this?

                                • 13. Re: Commit transaction after each service task?
                                  Richard Evans Newbie

                                  I don't really understand what you mean here. You can certainly run many processes each with many service tasks against a single ksession. The calls to completeWorkitem will be serialised but the time spent in these if all your service tasks execute asynchronously is small.

                                  • 14. Re: Commit transaction after each service task?
                                    Rahul Agrawal Newbie

                                    Yes I agree. That is what ideally should happen. But the issue is in case asynchronus service tasks the data base is not updated. The logs show that my process is pending with the service task. It is not completed.

                                    1 2 Previous Next