Flowable18取消事件------------持续更新中

简单来说,取消事件是专门用来处理事务性操作失败并进行回滚的机制。它总是与事务子流程 (Transaction Subprocess) 配合使用,是实现业务流程中“要么全部成功,要么全部回滚”这种原子性操作的关键。

该事件分类比较少只有两种。
1. 取消结束事件 (Cancel End Event)
这个事件用来触发一个取消动作。
图标: 一个带有实心“X”的粗边圆圈。
位置: 只能放置在事务子流程 (Transaction Subprocess) 的内部。(不然会失效!!!!!!!)
作用: 当流程执行到事务子流程内部的这个“取消结束事件”时,它会立即中断子流程当前的执行,并抛出一个“取消”信号。这个信号的目的是告诉外部“这个事务失败了,需要回滚”。
你可以把它想象成在代码块中抛出了一个RollbackException异常。
2. 取消边界事件 (Cancel Boundary Event)
这个事件用来捕获取消动作,并处理后续逻辑。
图标: 一个附着在活动边框上的、带有实心“X”的双边圆圈。
位置: 只能附着在事务子流程的边界上(不然会失效)
作用: 它的唯一作用就是等待并捕获其所附着的事务子流程内部抛出的“取消”信号。一旦捕获到信号,它会执行以下两个核心动作:
回滚事务: 中断事务子流程中所有正在进行的活动,并**自动撤销(回滚)**所有在这个事务中已经成功完成的活动。Flowable通过补偿(Compensation)机制来隐式实现回滚。
改变流程路径: 流程将从这个边界事件引出的路径继续往下执行,通常这条路径会通向一些处理失败的逻辑,比如“通知用户订单失败”、“记录失败日志”等。

下面我将提供一个非常典型的企业级业务场景——在线下单流程——的BPMN 2.0文件示例。这个场景完美地诠释了取消事件的用途。
业务场景描述
一个客户在电商网站下单,系统需要在一个事务内完成以下三件事:
创建订单: 在数据库中生成一条订单记录。
锁定库存: 为该订单预留商品库存。
处理支付: 调用支付网关进行扣款。
业务规则: 这三个步骤必须构成一个原子操作。如果支付失败,那么之前创建的订单记录必须被删除,锁定的库存也必须被释放。整个下单操作就像从未发生过一样。

<?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:flowable="http://flowable.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.flowable.org/processdef">

  <process id="orderProcessingWithCancel" name="在线下单流程(含取消回滚)" isExecutable="true">

    <startEvent id="start" name="客户提交订单"/>

    <!-- 事务子流程: 包含所有需要原子性操作的任务 -->
    <transaction id="orderTransactionSubProcess" name="处理订单事务">
      <startEvent id="subStart"/>

      <!-- 步骤1: 创建订单 (可补偿) -->
      <serviceTask id="createOrderTask" name="创建订单记录"
                   flowable:class="com.example.CreateOrderDelegate"
                   isForCompensation="true"/>

      <!-- 步骤2: 锁定库存 (可补偿) -->
      <serviceTask id="reserveInventoryTask" name="锁定商品库存"
                   flowable:class="com.example.ReserveInventoryDelegate"
                   isForCompensation="true"/>

      <!-- 步骤3: 处理支付 -->
      <serviceTask id="processPaymentTask" name="处理支付"
                   flowable:class="com.example.ProcessPaymentDelegate"/>

      <!-- 支付结果判断 -->
      <exclusiveGateway id="paymentGateway" name="支付是否成功?"/>

      <!-- 支付成功路径 -->
      <endEvent id="subEndSuccess" name="事务成功"/>

      <!-- 支付失败路径 -> 触发取消 -->
      <endEvent id="cancelOrderEndEvent" name="支付失败,取消事务">
        <cancelEventDefinition/>
      </endEvent>

      <!-- 子流程内部流转 -->
      <sequenceFlow sourceRef="subStart" targetRef="createOrderTask"/>
      <sequenceFlow sourceRef="createOrderTask" targetRef="reserveInventoryTask"/>
      <sequenceFlow sourceRef="reserveInventoryTask" targetRef="processPaymentTask"/>
      <sequenceFlow sourceRef="processPaymentTask" targetRef="paymentGateway"/>
      <sequenceFlow id="flowPaymentSuccess" sourceRef="paymentGateway" targetRef="subEndSuccess">
        <conditionExpression xsi:type="tFormalExpression">${paymentSuccess == true}</conditionExpression>
      </sequenceFlow>
      <sequenceFlow id="flowPaymentFailed" sourceRef="paymentGateway" targetRef="cancelOrderEndEvent">
        <conditionExpression xsi:type="tFormalExpression">${paymentSuccess == false}</conditionExpression>
      </sequenceFlow>

      <!-- 补偿任务定义 -->
      <!-- 补偿"创建订单"的任务 -->
      <serviceTask id="deleteOrderTask" name="补偿:删除订单记录"
                   isForCompensation="true"
                   flowable:class="com.example.DeleteOrderDelegate"/>
      <association associationDirection="One" sourceRef="deleteOrderTask" targetRef="createOrderTask"/>

      <!-- 补偿"锁定库存"的任务 -->
      <serviceTask id="releaseInventoryTask" name="补偿:释放库存"
                   isForCompensation="true"
                   flowable:class="com.example.ReleaseInventoryDelegate"/>
      <association associationDirection="One" sourceRef="releaseInventoryTask" targetRef="reserveInventoryTask"/>

    </transaction>

    <!-- 边界取消事件: 捕获事务失败信号 -->
    <boundaryEvent id="cancelBoundaryEvent" attachedToRef="orderTransactionSubProcess">
      <cancelEventDefinition/>
    </boundaryEvent>

    <!-- 正常成功路径 -->
    <serviceTask id="sendOrderConfirmationTask" name="发送订单成功通知"
                 flowable:class="com.example.SendConfirmationDelegate"/>
    <endEvent id="endSuccess" name="流程正常结束"/>

    <!-- 失败处理路径 -->
    <serviceTask id="notifyUserOfFailureTask" name="通知用户下单失败"
                 flowable:class="com.example.SendFailureNotificationDelegate"/>
    <endEvent id="endFailure" name="流程异常结束"/>

    <!-- 主流程流转 -->
    <sequenceFlow sourceRef="start" targetRef="orderTransactionSubProcess"/>
    <sequenceFlow sourceRef="orderTransactionSubProcess" targetRef="sendOrderConfirmationTask"/>
    <sequenceFlow sourceRef="sendOrderConfirmationTask" targetRef="endSuccess"/>

    <sequenceFlow sourceRef="cancelBoundaryEvent" targetRef="notifyUserOfFailureTask"/>
    <sequenceFlow sourceRef="notifyUserOfFailureTask" targetRef="endFailure"/>
  </process>

  <!-- BPMN图定义 (为了在Modeler中正确显示) -->
  <bpmndi:BPMNDiagram id="BPMNDiagram_orderProcessingWithCancel">
    <!-- ... 此处省略了详细的坐标信息,但文件在工具中可以自动生成或解析 ... -->
  </bpmndi:BPMNDiagram>

</definitions>

流程关键节点解析

(事务子流程)
这是核心,它将“创建订单”、“锁定库存”和“处理支付”捆绑成一个逻辑单元。Flowable会确保这个子流程的原子性。
(可补偿任务)
isForCompensation=“true” 这个属性非常重要,它标记这个任务是可以被撤销的。只有被标记的任务,在事务回滚时才会被补偿。
createOrderTask 和 reserveInventoryTask 都被标记了。
(取消结束事件)
当支付失败(paymentSuccess == false),流程会走到这里。这个事件的作用就是抛出一个“取消信号”,请求回滚整个事务。
(取消边界事件)
它像一个监听器,附着在事务子流程的边界上,专门等待内部抛出的“取消信号”。
(补偿任务)
这些任务是用来“反向操作”的。例如,deleteOrderTask 的逻辑就是删除订单。
标签将补偿任务(deleteOrderTask)与它要补偿的原始任务(createOrderTask)关联起来。

失败处理流程
一旦cancelBoundaryEvent被触发,流程会沿着它引出的路径继续,即执行 notifyUserOfFailureTask (通知用户下单失败)。

模拟执行流程

场景一:支付成功
流程进入 orderTransactionSubProcess。
createOrderTask 执行成功(订单已创建)。
reserveInventoryTask 执行成功(库存已锁定)。
processPaymentTask 执行成功,并设置流程变量 paymentSuccess = true。
支付网关判断条件为 true,流程走向 subEndSuccess。
事务子流程成功完成,所有操作被提交。
流程离开子流程,继续执行 sendOrderConfirmationTask (发送成功通知),然后正常结束。
场景二:支付失败(取消事件的核心)
流程进入 orderTransactionSubProcess。
createOrderTask 执行成功(订单已创建)。
reserveInventoryTask 执行成功(库存已锁定)。
processPaymentTask 执行失败,设置流程变量 paymentSuccess = false。
支付网关判断条件为 false,流程走向 cancelOrderEndEvent。
cancelOrderEndEvent 被触发,抛出取消信号。
cancelBoundaryEvent 捕获到该信号。
Flowable 引擎自动执行回滚操作:
它会查找事务内所有已完成且可补偿的任务。
它会按照完成顺序的逆序来执行补偿任务。
首先执行 releaseInventoryTask(释放库存)。
然后执行 deleteOrderTask(删除订单)。
回滚完成后,流程从 cancelBoundaryEvent 引出的路径继续执行,即 notifyUserOfFailureTask(通知用户下单失败),然后流程结束。
这个例子清晰地展示了如何使用取消事件来建模需要“全有或全无”的业务逻辑,而无需在代码中编写复杂的、易出错的状态管理和回滚代码。整个回滚过程由流程引擎根据模型声明自动完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值