AnsweredAssumed Answered

Activiti 5.16 feature preview - async parallel/inclusive gateways

Question asked by rickm on Nov 11, 2014
Latest reply on Nov 26, 2014 by holysoul
Hi,

I was pleased to see Tijs' posting in July, http://bpmn20inaction.blogspot.com/2014/07/activiti-516-feature-preview.html, announcing that version 5.16 adds support for joining async non-exclusive gateways no longer required using Apache Camel (or similar) to avoid optimistic locking exceptions on the joining gateway. 

However when I try out the simple example in the posting, it does not seem to work.  Can someone point me to the errors in my ways, I've been trying various approaches but as yet have no success.

Details below, my intent is to reproduce Tijs example above.

TIA,
Rick

Process2.BPMN file:
<blockcode>
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
  <process id="Process2" name="Process2" isExecutable="true">
    <startEvent id="startevent1" name="Start"></startEvent>
    <parallelGateway id="parallelgateway1" name="Parallel Gateway"></parallelGateway>
    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="parallelgateway1"></sequenceFlow>
    <serviceTask id="Task2" name="Task 2" activiti:async="true" activiti:exclusive="false" activiti:class="tasks.Task_Test"></serviceTask>
    <sequenceFlow id="flow2" sourceRef="parallelgateway1" targetRef="Task2"></sequenceFlow>
    <serviceTask id="Task1" name="Task 1" activiti:async="true" activiti:exclusive="false" activiti:class="tasks.Task_Test"></serviceTask>
    <sequenceFlow id="flow3" sourceRef="parallelgateway1" targetRef="Task1"></sequenceFlow>
    <parallelGateway id="parallelgateway2" name="Parallel Gateway" activiti:async="true" activiti:exclusive="true"></parallelGateway>
    <sequenceFlow id="flow4" sourceRef="Task1" targetRef="parallelgateway2"></sequenceFlow>
    <sequenceFlow id="flow5" sourceRef="Task2" targetRef="parallelgateway2"></sequenceFlow>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow6" sourceRef="parallelgateway2" targetRef="endevent1"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_Process2">
    <bpmndi:BPMNPlane bpmnElement="Process2" id="BPMNPlane_Process2">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="150.0" y="319.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="parallelgateway1" id="BPMNShape_parallelgateway1">
        <omgdc:Bounds height="40.0" width="40.0" x="220.0" y="316.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="Task2" id="BPMNShape_Task2">
        <omgdc:Bounds height="55.0" width="105.0" x="290.0" y="390.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="Task1" id="BPMNShape_Task1">
        <omgdc:Bounds height="55.0" width="105.0" x="290.0" y="230.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="parallelgateway2" id="BPMNShape_parallelgateway2">
        <omgdc:Bounds height="40.0" width="40.0" x="430.0" y="316.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="510.0" y="319.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="185.0" y="336.0"></omgdi:waypoint>
        <omgdi:waypoint x="220.0" y="336.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="240.0" y="356.0"></omgdi:waypoint>
        <omgdi:waypoint x="240.0" y="417.0"></omgdi:waypoint>
        <omgdi:waypoint x="290.0" y="417.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
        <omgdi:waypoint x="240.0" y="316.0"></omgdi:waypoint>
        <omgdi:waypoint x="240.0" y="257.0"></omgdi:waypoint>
        <omgdi:waypoint x="290.0" y="257.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
        <omgdi:waypoint x="395.0" y="257.0"></omgdi:waypoint>
        <omgdi:waypoint x="450.0" y="257.0"></omgdi:waypoint>
        <omgdi:waypoint x="450.0" y="316.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
        <omgdi:waypoint x="395.0" y="417.0"></omgdi:waypoint>
        <omgdi:waypoint x="450.0" y="417.0"></omgdi:waypoint>
        <omgdi:waypoint x="450.0" y="356.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
        <omgdi:waypoint x="470.0" y="336.0"></omgdi:waypoint>
        <omgdi:waypoint x="510.0" y="336.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>
</blockcode>

Task_Test.java:
<blockcode>
package tasks;

import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;


public class Task_Test implements JavaDelegate {

   @Override
   public void execute(DelegateExecution context) throws Exception {
      System.out.println("Executing activity: " + context.getCurrentActivityName());
      
      Thread.sleep(100);
   }
}
</blockcode>

Tomcat console output:
Starting Process ID Process2
Executing activity: Task 2
Executing activity: Task 1
Exception in thread "pool-1-thread-1" org.activiti.engine.ActivitiOptimisticLockingException: ProcessInstance[8428] was updated by another transaction concurrently
   at org.activiti.engine.impl.db.DbSqlSession.flushUpdates(DbSqlSession.java:562)
   at org.activiti.engine.impl.db.DbSqlSession.flush(DbSqlSession.java:444)
   at org.activiti.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:170)
   at org.activiti.engine.impl.interceptor.CommandContext.close(CommandContext.java:117)
   at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:66)
   at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:31)
   at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:40)
   at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:35)
   at org.activiti.engine.impl.jobexecutor.ExecuteJobsRunnable.run(ExecuteJobsRunnable.java:46)
   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
   at java.lang.Thread.run(Thread.java:745)

Outcomes