cancel
Showing results for 
Search instead for 
Did you mean: 

Exclusive Gateway in Compensation Flow

gokceng1
Champ in-the-making
Champ in-the-making
Hello, I know it is a long shot but I want to learn your thoughts about some point.
I've added a process definition to the post, do you think it is valid, and how activiti handles this.

*I couldn't add my process definition as an attachment, you it is here:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://sourceforge.net/bpmn/definitions/_1362775526812" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:yaoqiang="http://bpmn.sourceforge.net" exporter="Yaoqiang BPMN Editor" exporterVersion="2.1.12 For My Lovely Wife Cher" expressionLanguage="http://www.w3.org/1999/XPath" id="_1362775526812" name="" targetNamespace="http://sourceforge.net/bpmn/definitions/_1362775526812" typeLanguage="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL http://bpmn.sourceforge.net/schemas/BPMN20.xsd">
  <process id="PROCESS_COMP" isClosed="false" isExecutable="true" processType="None">
    <startEvent id="_2" isInterrupting="true" name="Start Event" parallelMultiple="false">
      <outgoing>_4</outgoing>
    </startEvent>
    <scriptTask completionQuantity="1" id="_3" isForCompensation="false" name="1" scriptFormat="groovy" startQuantity="1">
      <incoming>_4</incoming>
      <outgoing>_6</outgoing>
      <script><![CDATA[out:println execution.getCurrentActivityName();]]></script>
    </scriptTask>
    <sequenceFlow id="_4" sourceRef="_2" targetRef="_3"/>
    <intermediateThrowEvent id="_5" name="Intermediate Throw Event">
      <incoming>_6</incoming>
      <outgoing>_17</outgoing>
      <compensateEventDefinition id="_5_ED_1" waitForCompletion="true"/>
    </intermediateThrowEvent>
    <sequenceFlow id="_6" sourceRef="_3" targetRef="_5"/>
    <endEvent id="_7" name="End Event">
      <incoming>_18</incoming>
    </endEvent>
    <boundaryEvent attachedToRef="_3" cancelActivity="true" id="_9" name="Boundary Event" parallelMultiple="false">
      <compensateEventDefinition id="_9_ED_1" waitForCompletion="true"/>
    </boundaryEvent>
    <scriptTask completionQuantity="1" id="_10" isForCompensation="true" name="3" scriptFormat="groovy" startQuantity="1">
      <outgoing>_13</outgoing>
      <script><![CDATA[cond = 0;
out:println execution.getCurrentActivityName();]]></script>
    </scriptTask>
    <exclusiveGateway gatewayDirection="Unspecified" id="_12" name="Exclusive Gateway">
      <incoming>_13</incoming>
      <outgoing>_19</outgoing>
      <outgoing>_20</outgoing>
    </exclusiveGateway>
    <sequenceFlow id="_13" sourceRef="_10" targetRef="_12"/>
    <scriptTask completionQuantity="1" id="_14" isForCompensation="true" name="4" scriptFormat="groovy" startQuantity="1">
      <incoming>_19</incoming>
      <script><![CDATA[out:println execution.getCurrentActivityName();]]></script>
    </scriptTask>
    <scriptTask completionQuantity="1" id="_15" isForCompensation="true" name="5" scriptFormat="groovy" startQuantity="1">
      <incoming>_20</incoming>
      <script><![CDATA[out:println execution.getCurrentActivityName();]]></script>
    </scriptTask>
    <scriptTask completionQuantity="1" id="_16" isForCompensation="false" name="2" scriptFormat="groovy" startQuantity="1">
      <incoming>_17</incoming>
      <outgoing>_18</outgoing>
      <script><![CDATA[out:println execution.getCurrentActivityName();]]></script>
    </scriptTask>
    <sequenceFlow id="_17" sourceRef="_5" targetRef="_16"/>
    <sequenceFlow id="_18" sourceRef="_16" targetRef="_7"/>
    <sequenceFlow id="_19" sourceRef="_12" targetRef="_14">
      <conditionExpression><![CDATA[${cond == 1}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="_20" sourceRef="_12" targetRef="_15">
      <conditionExpression><![CDATA[${cond == 0}]]></conditionExpression>
    </sequenceFlow>
    <association associationDirection="One" id="_11" sourceRef="_9" targetRef="_10"/>
  </process>
  <bpmndi:BPMNDiagram documentation="background=#FFFFFF;count=1;horizontalcount=1;orientation=0;width=597.6;height=842.4;imageableWidth=587.6;imageableHeight=832.4;imageableX=5.0;imageableY=5.0" id="Yaoqiang_Diagram-_1" name="New Diagram">
    <bpmndi:BPMNPlane bpmnElement="PROCESS_COMP">
      <bpmndi:BPMNShape bpmnElement="_2" id="Yaoqiang-_2">
        <dc:Bounds height="32.0" width="32.0" x="180.0" y="295.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_3" id="Yaoqiang-_3">
        <dc:Bounds height="59.0" width="95.0" x="272.0" y="281.5"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="59.0" width="95.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_5" id="Yaoqiang-_5">
        <dc:Bounds height="32.0" width="32.0" x="427.0" y="295.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_7" id="Yaoqiang-_7">
        <dc:Bounds height="32.0" width="32.0" x="664.0" y="295.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_10" id="Yaoqiang-_10">
        <dc:Bounds height="55.0" width="85.0" x="427.0" y="378.5"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_12" id="Yaoqiang-_12" isMarkerVisible="true">
        <dc:Bounds height="42.0" width="42.0" x="572.0" y="385.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="42.0" width="42.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_14" id="Yaoqiang-_14">
        <dc:Bounds height="55.0" width="85.0" x="674.0" y="331.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_15" id="Yaoqiang-_15">
        <dc:Bounds height="55.0" width="85.0" x="674.0" y="426.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_16" id="Yaoqiang-_16">
        <dc:Bounds height="55.0" width="85.0" x="519.0" y="283.5"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_9" id="Yaoqiang-_9">
        <dc:Bounds height="32.0" width="32.0" x="292.0" y="324.5"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="1.0" x="20.0" y="-16.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="_19" id="Yaoqiang-_19" sourceElement="_12" targetElement="_14">
        <di:waypoint x="614.5" y="406.0"/>
        <di:waypoint x="674.5" y="358.5"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_18" id="Yaoqiang-_18" sourceElement="_16" targetElement="_7">
        <di:waypoint x="604.5" y="311.0"/>
        <di:waypoint x="664.5" y="311.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_17" id="Yaoqiang-_17" sourceElement="_5" targetElement="_16">
        <di:waypoint x="459.5" y="311.0"/>
        <di:waypoint x="519.5" y="311.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_13" id="Yaoqiang-_13" sourceElement="_10" targetElement="_12">
        <di:waypoint x="512.5" y="406.0"/>
        <di:waypoint x="572.5" y="406.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_6" id="Yaoqiang-_6" sourceElement="_3" targetElement="_5">
        <di:waypoint x="367.5" y="311.0"/>
        <di:waypoint x="427.5" y="311.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_4" id="Yaoqiang-_4" sourceElement="_2" targetElement="_3">
        <di:waypoint x="212.5" y="311.0"/>
        <di:waypoint x="272.5" y="311.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_20" id="Yaoqiang-_20" sourceElement="_12" targetElement="_15">
        <di:waypoint x="614.5" y="406.0"/>
        <di:waypoint x="674.5" y="453.5"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_11" id="Yaoqiang-_11" sourceElement="_9" targetElement="_10">
        <di:waypoint x="324.4921855917195" y="340.5"/>
        <di:waypoint x="427.5" y="406.0"/>
        <bpmndi:BPMNLabel>
          <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

EDIT: I saw this at user guide:
Compensation handlers must not have incoming or outgoing sequence flows.
So this approach should not be used although it works, am I right?
3 REPLIES 3

jbarrez
Star Contributor
Star Contributor
There's only one way and try it in code 🙂

It does look valid, but I dont have all the details of compensation handlers fresh in my mind at the moment.

gokceng1
Champ in-the-making
Champ in-the-making
I've tried, and it worked when it has only script tasks Smiley Happy
I've problem when implementing same thing with composition of other task types, it gives some exception about compensation, I know you want me to prepare some test case but it doesn't happen when I simplified process Smiley Happy

I will try to find the erroneous point in my process and tell about the situation in a few days.

jbarrez
Star Contributor
Star Contributor
Ok, perfect. Keep us posted!