Using CallActivity

Hello,

We are using the callActivity in our project and we have faced the following issue(sorry I do not have diagram):
We out the callActivity element, and configured it to run in parallel, in our diagram and we expected to:

  1. Each item to be processed in parallel of the others
  2. The result was, the first two items were processes in parallel and the other were synchronized.

Example execution(the collection of the items is a list of ints starting from 1 to N, each sub-process prints the integer as the process is started):

  1. We saw 1 or 2 produced on the output(the order is undetermined because the first two are executed in parallel)
  2. Then, we see 3, 4, 5, 6, … N

That lead me to the thought that this could a problem.
Could you tell me whether there is some problem in the callActivity?

Thanks and best regards,
Encho

Hi Encho,

I would have a look on jobExecutor configuration.

Martin

Hi Encho,

If you set the multi instance element to run in parallel, this means that there will be multiple call activities started without waiting for the other ones to finish first (like it would be the case with sequential). So it’s not parallel on a thread level. If you want real parallel behaviour with multiple threads executing the call activities at the same time, then the first step in the sub process that is started with the call activity should be async. Then you will see multiple sub processes being executed at the same time.

Best regards,

Tijs

Hello,

Thanks for the responses.
Martin, we have configured our jobExecutor to support asynchronous executions.
Tijs, the configuration which you described is in place…
Also, I want to mention something more. I have seen an OptimisticLockingException which is caused during the execution of the sub-processes.
Have you seen something like that before?

Thanks,
Encho

Optimistic locking exception is thrown when object (e.g. process, case) update was not performed. It means that object’s revision was already changed and update was referencing wrong object revision.

Regards
Martin

Hello Martin,

Yes, I understand the OptimisticLockingException but the problem is that it is happening when I want to start >20 parallel sub-processes using CallActivity.
Is there some way to provide a test for this? Jira item?

Thanks

Hi,

You can check why it is happening by yourself. Or:

mvn archetype:generate -DarchetypeGroupId=org.flowable -DarchetypeArtifactId=flowable-archetype-unittest -DarchetypeVersion=6.3.1

Regards
Martin

Hi,

I have written an unit test:
import org.flowable.engine.test.Deployment;
import org.flowable.engine.test.FlowableRule;
import org.junit.Rule;
import org.junit.Test;

public class MyUnitTest {

@Rule
public FlowableRule flowableRule = new FlowableRule();

@Test
@Deployment(resources = { "diagrams/main-process.bpmn", "diagrams/sub-process.bpmn" })
public void test() throws Exception {
    flowableRule.getRuntimeService()
        .startProcessInstanceByKey("mainProcess");
    Thread.sleep(1000000000);
}

}

The problem is that it is not running( I cannot see the output of the processes).
The flowable.cfg.xml:

<?xml version="1.0" encoding="UTF-8"?>
<property name="jdbcUrl" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
<property name="jdbcDriver" value="org.h2.Driver" />
<property name="jdbcUsername" value="sa" />
<property name="jdbcPassword" value="" />

Could you give me hint?

Thanks,
Encho

create a project on github and paste the link

In the parallel.flowable.test.Test i have created deployment and process instance based on the diagram which is located in src/main/resources/diagrams/holiday-request.bpmn20.xml. The process instance is created successfully and I have dumped the execution for the process instance and the result is 2 executions: one is with ActivityId = null and the other one with ActivityId=approveTask and this is stuck in the while loop(The process never ends and the ActivityId is not changed - the ActivityId is always approveTask).
Could you tell me what I have done wrong?

In my team we are moving from Activiti to Flowable, please ignore if somewhere the Activiti word is mentioned :slight_smile:

I would really appreciate some help :slight_smile:

Thanks,
Encho

Hi Encho,

Thanks a lot for the test. I did some changes there because it did not fail. :slight_smile: See attached patch. (If you allow me to push to your example it could be faster.)

The exception which I’ve got is :

Caused by: org.h2.jdbc.JdbcSQLException: 

Deadlock detected. The current transaction was rolled back. Details: "
    Session #4 (user: SA) is waiting to lock PUBLIC.ACT_RU_JOB while locking PUBLIC.ACT_RU_EXECUTION (exclusive), PUBLIC.ACT_HI_VARINST (exclusive), PUBLIC.ACT_HI_PROCINST (exclusive), PUBLIC.ACT_HI_ACTINST (exclusive), PUBLIC.ACT_RU_VARIABLE (exclusive).
    Session #2 (user: SA) is waiting to lock PUBLIC.ACT_RU_EXECUTION while locking PUBLIC.ACT_RU_JOB (exclusive)."; SQL statement:
    insert into ACT_RU_JOB (

Is this the error which you want to solve? (I did not find any optimistic locking exception)
BTW. I found similar test in flowable source org.flowable.engine.test.bpmn.async.AsyncTaskTest#testAsyncCallActivity

Regards
Martin

Patch:

Index: src/main/resources/diagrams/main-process.bpmn
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/main/resources/diagrams/main-process.bpmn	(revision b86115e66edf3913191842e4b1391abbde0fccf3)
+++ src/main/resources/diagrams/main-process.bpmn	(revision 551f374c8597e691ddd1597bd4d746e37389611d)
@@ -12,7 +12,7 @@
   <process id="mainProcess" name="Main Process" isExecutable="true">
     <startEvent id="startevent1" name="Start"></startEvent>
     <endEvent id="endevent1" name="End"></endEvent>
-    <serviceTask id="servicetask1" name="Set MessagesSet Messages" flowable:async="true" flowable:class="parallel.activiti.test.SetMessageTask"></serviceTask>
+    <serviceTask id="servicetask1" name="Set MessagesSet Messages" flowable:async="true" flowable:class="parallel.flowable.test.SetMessageTask"></serviceTask>
     <callActivity id="callactivity1" name="Call activity" flowable:async="true" calledElement="subProcess" flowable:inheritVariables="false">
       <extensionElements>
         <flowable:in source="message" target="message"></flowable:in>
Index: src/main/resources/diagrams/sub-process.bpmn
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/main/resources/diagrams/sub-process.bpmn	(revision b86115e66edf3913191842e4b1391abbde0fccf3)
+++ src/main/resources/diagrams/sub-process.bpmn	(revision 551f374c8597e691ddd1597bd4d746e37389611d)
@@ -12,7 +12,7 @@
     <process id="subProcess" name="Siub Process" isExecutable="true">
     <startEvent id="startevent1" name="Start"></startEvent>
     <endEvent id="endevent1" name="End"></endEvent>
-    <serviceTask id="servicetask1" name="Display Message" flowable:async="true" flowable:class="parallel.activiti.test.DisplayMessageTask"></serviceTask>
+    <serviceTask id="servicetask1" name="Display Message" flowable:async="false" flowable:class="parallel.flowable.test.DisplayMessageTask"></serviceTask>
     <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="servicetask1"></sequenceFlow>
     <sequenceFlow id="flow2" sourceRef="servicetask1" targetRef="endevent1"></sequenceFlow>
   </process>
Index: src/test/java/parallel/flowable/test/MyUnitTest.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/test/java/parallel/flowable/test/MyUnitTest.java	(revision b86115e66edf3913191842e4b1391abbde0fccf3)
+++ src/test/java/parallel/flowable/test/MyUnitTest.java	(revision 551f374c8597e691ddd1597bd4d746e37389611d)
@@ -5,6 +5,8 @@
 import org.flowable.engine.RepositoryService;
 import org.flowable.engine.RuntimeService;
 import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration;
+import org.flowable.engine.impl.test.JobTestHelper;
+import org.flowable.engine.impl.test.TestHelper;
 import org.flowable.engine.repository.Deployment;
 import org.flowable.engine.repository.ProcessDefinition;
 import org.flowable.engine.runtime.ProcessInstance;
@@ -19,13 +21,8 @@
 
     @Test
     public void test2() throws InterruptedException {
-        ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:h2:mem:flowable;DB_CLOSE_DELAY=-1")
-            .setJdbcUsername("sa")
-            .setJdbcPassword("")
-            .setJdbcDriver("org.h2.Driver")
-            .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
 
-        ProcessEngine processEngine = cfg.buildProcessEngine();
+        ProcessEngine processEngine = flowableRule.getProcessEngine();
         RepositoryService repositoryService = processEngine.getRepositoryService();
         Deployment deployment = repositoryService.createDeployment()
             .addClasspathResource("diagrams/main-process.bpmn")
@@ -49,7 +46,7 @@
         ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("mainProcess");
         System.out.println("Process instance id: " + processInstance.getProcessInstanceId());
         // System.out.println("Process instance running: " processInstance.get);
-        Thread.sleep(10000000);
+        JobTestHelper.waitForJobExecutorToProcessAllJobsAndExecutableTimerJobs(flowableRule.getProcessEngine().getProcessEngineConfiguration(), flowableRule.getManagementService(), 100000, 200);
     }
 
 }

I have added you as collaborator :slight_smile:

Also, yes, the error about the
Caused by: org.h2.jdbc.JdbcSQLException:

Deadlock detected. The current transaction was rolled back. Details: "
Session #4 (user: SA) is waiting to lock PUBLIC.ACT_RU_JOB while locking PUBLIC.ACT_RU_EXECUTION (exclusive), PUBLIC.ACT_HI_VARINST (exclusive), PUBLIC.ACT_HI_PROCINST (exclusive), PUBLIC.ACT_HI_ACTINST (exclusive), PUBLIC.ACT_RU_VARIABLE (exclusive).
Session #2 (user: SA) is waiting to lock PUBLIC.ACT_RU_EXECUTION while locking PUBLIC.ACT_RU_JOB (exclusive)."; SQL statement:
insert into ACT_RU_JOB (
is what I want to solve.

Encho,

The problem is in h2 configuration. H2 locks the whole tables and not exact rows.
Change config and rerun your test

jdbc:h2:mem:flowable;DB_CLOSE_DELAY=1000;MVCC=TRUE

Regards
Martin

Hello Martin,

Thanks for the explanation.
I have added a new test in the MyTest.java class which uses the flowable.cfg.xml.
The problem is that the process is started but I cannot see any progress in it.
If you start the test, you will se a lot of nulls in the console(current ActivityId).

Could you help me with this?

Thanks,
Encho

Hi Encho,

process instance itself does not points to activityId. There is new execution created as a child of the process instance. you can query for it and get the activityId with

flowableRule.getRuntimeService().createExecutionQuery().parentId(procInst.getId()).singleResult().getActivityId()

Regards
Martin

Hi,

Okay but why the process is not finishing. I am not doing any work in the process - just printing something to the console.

Thanks,
Encho

Hi Encho,

The problem is that some of your Multiinstance asynchronous jobs fail because of optimistic locking exception. If job fails, a timer is created. Test waits on this timer to be finished.

Regards
Martin

Hi Martin,

But if I start a diagram which does not have CallActivity in it, the result is the same - I have a process which is not progressing at all.
Anyway, could you help me in order to resolve that? Why is this OptimisticLockingException thrown- what have caused it(or to ask, which two parallel transactions are executed against the same table at the same time)?

Regards,
Encho

Hello,

I have another question too, I see that VariableLocal is being used. Could you tell me when this local variable is transmitted to the database?

Thanks.

Hi Encho,

The value is inserted to the database at the session flush.

Regards
Martin