1 Reply Latest reply on Jun 10, 2014 7:35 AM by n_rajasekhar

    Separating JBPM 5.1 Process persistence from workitemhandler business logic transaction

    lakshmi.sampath

      Hi,

       

      I am persisting the knowledge session using JPA/JTA and I need to separate jbpm process related persistence from business logic persistence so that when I use asynchronous service work item handlers to call the business logic
      and if the business logic fails and rollbacks a transaction, I still want the process related information, history log and mainly the asynchronous work item to be persisted.

       

      Here's the exception thrown when JBPM tries to commit the asynchnous work item after the business logic called inside a workitem rollbacks a transaction.

      1. How do I make sure that JBPM uses a separate transaction always and not share it with the business logic transaction.
      2. Even if JBPM uses separate transaction, does it also rollback if business logic transaction rollbacks since they are part of same JTA User Transaction(Which I dont want JBPM to do).

       

      Note: Both JBPM persistence and business logic share the same database and datasource.

        

       

      2012-03-17 17:30:31,032 WARN [org.drools.persistence.jta.JtaTransactionManager] Unable to commit transaction

      javax.transaction.RollbackException: [com.arjuna.ats.internal.jta.transaction.arjunacore.commitwhenaborted] [com.arjuna.ats.internal.jta.transaction.arjunacore.commitwhenaborted] Can't commit because the transaction is in aborted state

      at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1394)

      at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:135)

      at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:87)

      at org.jboss.tm.usertx.client.ServerVMClientUserTransaction.commit(ServerVMClientUserTransaction.java:140)

      at org.drools.persistence.jta.JtaTransactionManager.commit(JtaTransactionManager.java:167)

      at org.drools.persistence.SingleSessionCommandService.execute(SingleSessionCommandService.java:294)

      at org.drools.command.impl.CommandBasedStatefulKnowledgeSession.startProcessInstance(CommandBasedStatefulKnowledgeSession.java:237)

      at com.hp.adam.processengine.impl.JBPMProcessEngine.startProcess(JBPMProcessEngine.java:35)

      ...

      Caused by: java.lang.IllegalStateException: BaseTransaction.rollback - [com.arjuna.ats.internal.jta.transaction.arjunacore.notx] [com.arjuna.ats.internal.jta.transaction.arjunacore.notx] no transaction!

      at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.rollback(BaseTransaction.java:158)

      at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.rollback(BaseTransactionManagerDelegate.java:126)

      at org.jboss.tm.usertx.client.ServerVMClientUserTransaction.rollback(ServerVMClientUserTransaction.java:148)

      at org.drools.persistence.jta.JtaTransactionManager.rollback(JtaTransactionManager.java:183)

      ... 21 more

       

       

      Here's how I am configuring and starting the process. Note that I autowire spring to retrieve transaction manager,
      primarily to get hold of UserTransaction object instead of lookup from JNDI.

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

       

      @Autowired

      org.springframework.transaction.jta.JtaTransactionManager txm;

       

      ...

       

      KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();

      kbase=kbuilder.newKnowledgeBase();

      kbuilder.add(ResourceFactory.newClassPathResource("bpmn2Process.bpmn"), ResourceType.BPMN2);

         

      EntityManagerFactory emf =  Persistence.createEntityManagerFactory("org.jbpm.persistence.jpa");

      Environment env = KnowledgeBaseFactory.newEnvironment();

      env.set( EnvironmentName.ENTITY_MANAGER_FACTORY, emf );

      env.set(EnvironmentName.TRANSACTION, txm.getUserTransaction());

         

      StatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession(kbase,null,env);

      ksession.getWorkItemManager().registerWorkItemHandler("ServiceWorkItem", (WorkItemHandler)object);

      JPAWorkingMemoryDbLogger processDbLogger = new JPAWorkingMemoryDbLogger(ksession);

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

       

      Also attached the persistence.xml file

       

      thanks

      lakshmi.