13 Replies Latest reply on Sep 17, 2013 5:10 AM by swiderski.maciej

    [JBPM 5.4] - Transaction / Concurrency problem

    guilherme.telles

      Hi, I'm having some trouble with concurrency, hope you guys can help me

       

      Here's the stack trace:

       

      ================================================================================================================================

       

      15:32:16,379 ERROR [org.drools.persistence.SingleSessionCommandService] (Thread-79) Could not commit session: java.lang.RuntimeException: Unable to commit transaction
          at org.drools.persistence.jta.JtaTransactionManager.commit(JtaTransactionManager.java:182) [drools-persistence-jpa-5.5.0.Final.jar:5.5.0.Final]
          at org.drools.persistence.SingleSessionCommandService.execute(SingleSessionCommandService.java:376) [drools-persistence-jpa-5.5.0.Final.jar:5.5.0.Final]
          at org.drools.command.impl.CommandBasedStatefulKnowledgeSession$1.completeWorkItem(CommandBasedStatefulKnowledgeSession.java:150) [drools-core-5.5.0.Final.jar:5.5.0.Final]
          at org.jbpm.process.workitem.wsht.AsyncGenericHTWorkItemHandler$GetResultContentResponseHandler.execute(AsyncGenericHTWorkItemHandler.java:302) [jbpm-human-task-core-5.4.0.Final.jar:5.4.0.Final]
          at org.jbpm.task.service.TaskClientHandler.messageReceived(TaskClientHandler.java:153) [jbpm-human-task-core-5.4.0.Final.jar:5.4.0.Final]
          at org.jbpm.task.service.hornetq.HornetQTaskClientHandler.messageReceived(HornetQTaskClientHandler.java:56) [jbpm-human-task-hornetq-5.4.0.Final.jar:5.4.0.Final]
          at org.jbpm.task.service.hornetq.HornetQTaskClientConnector$1.run(HornetQTaskClientConnector.java:122) [jbpm-human-task-hornetq-5.4.0.Final.jar:5.4.0.Final]
          at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_21]
      Caused by: javax.transaction.RollbackException: ARJUNA016053: Could not commit transaction.
          at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1177)
          at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:117)
          at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:75)
          at org.jboss.tm.usertx.client.ServerVMClientUserTransaction.commit(ServerVMClientUserTransaction.java:167)
          at org.drools.persistence.jta.JtaTransactionManager.commit(JtaTransactionManager.java:179) [drools-persistence-jpa-5.5.0.Final.jar:5.5.0.Final]
          ... 7 more
      Caused by: javax.persistence.OptimisticLockException: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [org.jbpm.persistence.processinstance.ProcessInstanceInfo#1]
          at org.hibernate.ejb.AbstractEntityManagerImpl.wrapStaleStateException(AbstractEntityManagerImpl.java:1389) [hibernate-entitymanager-4.1.0.Final.jar:4.1.0.Final]
          at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1307) [hibernate-entitymanager-4.1.0.Final.jar:4.1.0.Final]
          at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1288) [hibernate-entitymanager-4.1.0.Final.jar:4.1.0.Final]
          at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1294) [hibernate-entitymanager-4.1.0.Final.jar:4.1.0.Final]
          at org.hibernate.ejb.AbstractEntityManagerImpl$CallbackExceptionMapperImpl.mapManagedFlushFailure(AbstractEntityManagerImpl.java:1480) [hibernate-entitymanager-4.1.0.Final.jar:4.1.0.Final]
          at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:109) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
          at org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization.beforeCompletion(RegisteredSynchronization.java:53) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
          at com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.beforeCompletion(SynchronizationImple.java:76)
          at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.beforeCompletion(TwoPhaseCoordinator.java:273)
          at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:93)
          at com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:164)
          at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1165)
          ... 11 more
      Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [org.jbpm.persistence.processinstance.ProcessInstanceInfo#1]
          at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:2365) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
          at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3017) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
          at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2915) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
          at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3244) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
          at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:113) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
          at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
          at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:354) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
          at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:276) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
          at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
          at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
          at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1127) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
          at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:325) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
          at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:104) [hibernate-core-4.1.0.Final.jar:4.1.0.Final]
          ... 17 more
      

      ================================================================================================================================

       

      I'm using JBPM 5.4, Jboss AS 7.1.1, Spring 3

       

      The Knowledge Base is being kept in another server.

       

      This is how I start my HornetQTaskServer:

      (Do I really need to start it? I've been trying to connect to the one that's supposed to come with jBPM. But, in that case, even though I can start the process, not a single task is persisted. I can only complete the process if I set the AsyncHornetQHTWorkItemHandler IP to localhost and start the HornetQ locally  )

       

           try{
                  TaskService taskService = new TaskService(getEntityManagerFactoryJbpm(), SystemEventListenerFactory.getSystemEventListener());
                  HornetQTaskServer server = new HornetQTaskServer(taskService, "localhost", 5445);
                  if(!server.isRunning()) {
                      Thread thread = new Thread(server);
                      thread.start();
                  }
              } catch(Exception e) {
                  LOGGER.warn("HornetQ Task Server já iniciado");
           }
      

       

      My Environment:

       

          public Environment getEnvironment() {
      
              if(environment == null) {
                  LOGGER.info("CREATING NEW ENVIRONMENT");
      
                  environment = KnowledgeBaseFactory.newEnvironment();
                  environment.set(EnvironmentName.ENTITY_MANAGER_FACTORY, getEntityManagerFactoryJbpm());
              }
              return environment;
          }
      

       

      How I register my handlers:

       

      public static void registerHandlers(StatefulKnowledgeSession kSession) {
      
              LOGGER.info("REGISTERING HANDLERS...");
      
              final EmailHandler emailHandler = new EmailHandler();
              final OrcamentoHandler orcamentoHandler = new OrcamentoHandler();
              final MudarStatusHandler mudarStatusHandler = new MudarStatusHandler();
      
              kSession.getWorkItemManager().registerWorkItemHandler("notificacao_lider", emailHandler);
              kSession.getWorkItemManager().registerWorkItemHandler("notificacao_negocio", emailHandler);
              kSession.getWorkItemManager().registerWorkItemHandler("notificacao_responsavel", emailHandler);
              kSession.getWorkItemManager().registerWorkItemHandler("modulo_orcamento", orcamentoHandler);
              kSession.getWorkItemManager().registerWorkItemHandler("muda_status", mudarStatusHandler);
      
              TaskClient client = new TaskClient(new HornetQTaskClientConnector(UUID.randomUUID().toString(), new HornetQTaskClientHandler(SystemEventListenerFactory.getSystemEventListener())));
              TaskManager taskManager = new TaskManager();
      
              AsyncHornetQHTWorkItemHandler htHandler = new AsyncHornetQHTWorkItemHandler(taskClient, kSession, true);
              htHandler.setPort(5445);
              htHandler.connect();
              kSession.getWorkItemManager().registerWorkItemHandler("Human Task", htHandler);
        }
      

       

      Anyone have any insight? I've already searched the whole community, but nothing helped.

        • 1. Re: [JBPM 5.4] - Transaction / Concurrency problem
          swiderski.maciej

          if you have mulitple ksessions that different threads operate on you cannot share the environment object. Each session must have dedicated instance of Environment and looking at the code given you share environment.

           

           

          Guilherme Telles wrote:

          My Environment:

           

              public Environment getEnvironment() {
           
                  if(environment == null) {
                      LOGGER.info("CREATING NEW ENVIRONMENT");
           
                      environment = KnowledgeBaseFactory.newEnvironment();
                      environment.set(EnvironmentName.ENTITY_MANAGER_FACTORY, getEntityManagerFactoryJbpm());
                  }
                  return environment;
              }
          

           

          HTH

          • 2. Re: [JBPM 5.4] - Transaction / Concurrency problem
            guilherme.telles

            Maciej, thanks for answering

             

            I changed the code to the following:

             

                public Environment getEnvironment() {
             
                    LOGGER.info("CREATING NEW ENVIRONMENT");
             
                    environment = KnowledgeBaseFactory.newEnvironment();
                    environment.set(EnvironmentName.ENTITY_MANAGER_FACTORY, getEntityManagerFactoryJbpm());
                    
                    return environment;
                }

             

            So that everytime an Environment is needed, a new one is created.

             

            But I'm still getting the same error.

             

            There's some other cause to the error?

             

            Thanks!


            • 3. Re: [JBPM 5.4] - Transaction / Concurrency problem
              swiderski.maciej

              could you please describe your application configuration? Best would be to have sort of reproducer of this problem as it looks like some entity manger is cached somewhere and thus causing optimistic locking/stale object exception. In general the entity manager should be cleared at transaction completion but maybe that somehow does not work in spring - depending on transaction management. See here.

               

              HTH

              • 4. Re: [JBPM 5.4] - Transaction / Concurrency problem
                guilherme.telles

                Ok, I'll prepare a demo application for you.

                • 5. Re: [JBPM 5.4] - Transaction / Concurrency problem
                  guilherme.telles

                  I'm kind of busy to complete the demo application, but in the meanwhile, this is my application configuration you asked:

                   

                  • JBPM 5.4 - The process, knowlodge base, and etc it's in a remote server
                  • Spring 3
                    • My bean configuration for the entity manager factory:

                    

                       <bean id="entityManagerFactoryJbpm"

                          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

                          <property name="persistenceUnitName" value="org.jbpm.process" />

                       </bean>

                   

                  • JBoss 7.1.1: Here's my data source for the persistence of the process

                   

                                 <datasource jndi-name="java:jboss/datasources/processDS" pool-name="processDS" enabled="true" use-java-context="true">

                                      <connection-url>jdbc:postgresql://localhost:5432/mydatabase</connection-url>

                                      <driver-class>org.postgresql.Driver</driver-class>

                                      <driver>postgresql</driver>

                                      <security>

                                          <user-name>myuser</user-name>

                                          <password>mypassword</password>

                                      </security>

                                  </datasource>

                   

                   

                  What kind of information do you need?

                   

                  Thanks

                  • 6. Re: [JBPM 5.4] - Transaction / Concurrency problem
                    guilherme.telles

                    Maciej, here's the demo application, it's intructions are inside.

                     

                    Due to lack of time, it does not reproduces the same concurrency error.

                     

                    But maybe you can find what I'm doing wrong with this.

                     

                    Of course it's a very basic application and I had to simplify a lot of code.

                     

                    For example, getting a task service, adding users manually instead of using ldap, a local .bpmn2 file instead of a remote server, etc.

                     

                    I'm not sending a war file because of the forum attachment size limit.

                     

                    Thank you very much for helping me, I'm in kind of a tight spot here.

                    • 7. Re: [JBPM 5.4] - Transaction / Concurrency problem
                      paulo.porto

                      hey i'm also having the same trouble

                      • 8. Re: [JBPM 5.4] - Transaction / Concurrency problem
                        mvermand

                        I use multiple ksessions from a webApp servlet. I kept getting "Session is closed!" Exception from within "SingleSessionCommandService".

                        >Each session must have dedicated instance of Environment and looking at the code given you share environment.

                        This really saved my day!

                        Thanks a lot for that insigth!

                        • 9. Re: [JBPM 5.4] - Transaction / Concurrency problem
                          calca

                          Hey Guillerm.It seems you are reusing LocalTaskService.

                           

                          public EasyPieLocalTaskServiceImpl getHumanTaskService() {

                            if (humanTaskService == null) {

                            LOGGER.info("Generating Human Task Service");

                            TaskService taskService = new TaskService(new ProcessManager().getEntityManagerFactoryJbpm(), SystemEventListenerFactory.getSystemEventListener());

                            ProcessManager.createLdapCallback(taskService.createSession());

                            humanTaskService = new EasyPieLocalTaskServiceImpl();

                            humanTaskService.assignTaskClient(getTaskClient());

                            }

                            return humanTaskService;

                            }

                           

                          LocalTaskService is not thread safe, so you should create one per request or something like this

                          (Concurrency issue with LocalTaskService)

                           

                          Hope this helps!

                           

                          Demian

                          • 10. Re: [JBPM 5.4] - Transaction / Concurrency problem
                            guilherme.telles

                            Hi Demian, thanks for answering

                             

                            As I said, I don't use Task Service, in it's place I just create a ldapCallback. I just used it in the demo application.

                            • 11. Re: [JBPM 5.4] - Transaction / Concurrency problem
                              guilherme.telles

                              Does somebody has any idea to why this is happening?

                               

                              Thanks in advance

                              • 12. Re: [JBPM 5.4] - Transaction / Concurrency problem
                                paulo.porto

                                Please, anyone knows why this is happening??

                                • 13. Re: [JBPM 5.4] - Transaction / Concurrency problem
                                  swiderski.maciej

                                  this happens due to concurrent updates to the same process instance which in fact might be caused by number of factors so describing environment and how you use jBPM is of great value. Best is to start new thread where you could describe your environment usage scenarion and the exact steps that lead to this problem. With that there is much more probability that someone could help out.

                                   

                                  HTH