# 信号事件
# 核心概念
信号事件是BPMN规范中用于流程间通信的重要机制,它允许业务流程实例在特定信号发生时触发相应的处理逻辑。与消息事件不同,信号事件具有全局广播特性,当一个信号被抛出时,所有正在监听该信号的流程实例都会接收到此信号,无论这些流程实例属于哪个流程定义或处于哪个执行路径.
与消息事件相比,信号事件的核心区别在于其 广播性质。消息事件是点对点的通信,需要明确的发送者和接收者,而信号事件则更像是广播电台,一个信号抛出后,所有"调频"到该信号的流程实例都会做出响应。这种特性使得信号事件特别适合处理系统级别的全局事件,如系统维护通知、全局配置更新等需要多个流程实例同时响应的情况。
# 三类信号事件
# 信号启动事件
信号启动事件(Signal Start Event)允许流程实例在接收到特定信号时启动。与其他类型的启动事件不同,信号启动事件使流程能够响应全局信号,而不是由明确的API调用或定时器触发。
信号启动事件通常用于事件驱动的流程初始化。例如,在一个电商平台中,当系统检测到"黑色星期五"促销活动开始时,可以抛出一个 "促销开始"信号,所有订阅了该信号的商品上架流程、价格调整流程和库存准备流程都会自动启动。
<signal id="promotionStartSignal" name="promotionStartSignal" />
<process id="productListingProcess">
<startEvent id="signalStart">
<signalEventDefinition signalRef="promotionStartSignal" />
</startEvent>
<!-- 流程的其他部分 -->
</process>
# 信号中间捕获事件
信号中间捕获事件(Signal Intermediate Catching Event)是流程执行过程中等待特定信号的节点。当流程执行到该事件时,会暂停并等待,直到指定的信号被触发,然后继续执行后续流程。
与信号启动事件不同,信号中间捕获事件用于 运行中的流程实例,而不是启动新实例。它通常用于流程需要同步多个业务事件的场景。例如,在订单履约流程中,可能需要等待"付款确认"和"库存检查完成"两个信号都到达后,才能继续执行发货操作。
信号中间捕获事件的一个关键特性是它的持久性。即使流程实例在事件处等待了很长时间,甚至系统重启后,事件订阅仍然有效。当信号最终到达时,流程会从等待点继续执行。
<intermediateCatchEvent id="waitForPaymentSignal">
<signalEventDefinition signalRef="paymentConfirmedSignal" />
</intermediateCatchEvent>
在实际业务中,信号中间捕获事件常用于处理跨系统的异步操作。例如,一个流程可能调用外部支付网关后,在中间捕获事件处等待支付结果信号。这种模式使得流程能够优雅地处理外部系统的响应,提高业务的可靠性和用户体验。
# 信号边界事件
信号边界事件(Signal Boundary Event)是 附加在活动上的中断事件,它可以在活动执行过程中监听特定信号,并在信号到达时中断当前活动,沿边界事件的出口顺序流继续执行。
信号边界事件与其他边界事件(如定时器边界事件、错误边界事件)的关键区别在于其全局性和外部触发特性。它不仅可以捕获当前流程范围内抛出的信号,还能捕获来自其他流程实例或外部系统的信号。
边界事件的一个重要配置参数是cancelActivity属性,该属性决定当信号触发时是否中断所依附的活动。默认情况下,cancelActivity为true,意味着活动会被中断;如果设置为false,则活动继续执行,边界事件的行为类似于非中断事件。
<serviceTask id="processOrder" name="处理订单">
<boundaryEvent id="suspendBoundary" attachedToRef="processOrder">
<signalEventDefinition signalRef="emergencySuspendSignal" />
</boundaryEvent>
</serviceTask>
信号边界事件在异常处理和紧急操作场景中极为有用。例如,在检测到系统异常或需要紧急暂停所有操作时,管理员可以通过发送一个全局信号,中断所有正在执行特定任务的流程实例,使其转入异常处理流程。 信号边界事件还经常与多实例活动结合使用。当信号边界事件附加到多实例活动时,它可以影响单个实例或整个多实例活动,具体取决于引擎的实现和配置。这为处理复杂业务场景提供了极大的灵活性。