---
title: "13.5 Events"
chapter: "13 BPMN Execution Semantics"
source: "OMG BPMN 2.0.2 — formal/2013-12-09"
pages: "439-443"
---

> 13 BPMN Execution Semantics · páginas 439-443 · [índice](../README.md)


<a id="sec-13-5"></a>
## 13.5 Events


This sub clause describes the handling of **Events**.


<a id="sec-13-5-1"></a>
### 13.5.1 Start Events


For single **Start Events**, handling consists of starting a new **Process** *instance* each time the **Event** occurs. **Sequence Flows** leaving the **Event** are then followed as usual. If the **Start Event** participates in a **Conversation** that includes other **Start Events**, a new **Process** *instance* is only created if none already exists for the specific **Conversation** (identified through its associated correlation information) of the **Event** occurrence.


A **Process** can also be started via an **Event-Based Gateway**. In that case, the first matching **Event** will create a new *instance* of the **Process**, and waiting for the other **Events** originating from the same decision stops, following the usual semantics of the **Event-Based Exclusive Gateway**. Note that this is the only scenario where a **Gateway** can exist without *incoming* **Sequence Flows**. It is possible to have multiple groups of **Event-Based Gateways** starting a **Process**, provided they participate in the same **Conversation** and hence share the same correlation information. In that case, one **Event** out of each group needs to arrive; the first one creates a new **Process** *instance*, while the subsequent ones are routed to the existing *instance*, which is identified through its correlation information.


<a id="sec-13-5-2"></a>
### 13.5.2 Intermediate Events


For **Intermediate Events**, the handling consists of waiting for the **Event** to occur. Waiting starts when the **Intermediate Event** is reached. Once the **Event** occurs, it is consumed. **Sequence Flows** leaving the **Event** are followed as usual. For *catch* **Message Intermediate Events**, the **Message** *correlation* behavior is the same as for **Receive Tasks** (see sub clause 13.3.3).


<a id="sec-13-5-3"></a>
### 13.5.3 Intermediate Boundary Events


For boundary **Events**, handling first consists of consuming the **Event** occurrence. If the cancelActivity attribute is set, the **Activity** the **Event** is attached to is then cancelled (in case of a multi-instance, all its *instances* are cancelled); if the attribute is not set, the **Activity** continues execution (only possible for **Message**, **Signal**, **Timer**, and **Conditional Events**, not for **Error Events**). Execution then follows the **Sequence Flow** connected to the boundary **Event**. For *boundary* **Message Intermediate Events**, the **Message** *correlation* behavior is the same as for **Receive Tasks** (see sub clause 13.3.3).


<a id="sec-13-5-4"></a>
### 13.5.4 Event Sub-Processes


**Event Sub-Processes** allow to handle an **Event** within the context of a given **Sub-Processes** or **Process**. An **Event Sub-Process** always begins with a **Start Event**, followed by **Sequence Flows**. **Event Sub-Processes** are a special kind of **Sub-Process**: they create a scope and are instantiated like a **Sub-Process**, but they are not instantiated by normal control flow but only when the associated **Start Event** is triggered. **Event Sub-Processes** are self-contained and MUST not be connected to the rest of the **Sequence Flows** in the **Sub-Processes**; also they cannot have attached boundary **Events**. They run in the context of the **Sub-Process**, and thus have access to its context. An **Event Sub-Process** cancels execution of the enclosing **Sub-Process**, if the isInterrupting attribute of its **Start Event** is set; for a multi-instance **Activity** this cancels only the affected *instance*. If the isInterrupting attribute is not set (not possible for **Error Event Sub-Processes**), execution of the enclosing **Sub-Process** continues in parallel to the **Event Sub-Process**. An **Event Sub-Process** can optionally re-trigger the **Event** through which it was triggered, to cause its continuation outside the boundary of the associated **Sub-Process**. In that case the **Event Sub-Process** is performed when the **Event** occurs; then control passes to the boundary **Event**, possibly canceling the **Sub-Process** (including running handlers).


<a id="sec-operational-semantics"></a>
#### Operational semantics


An **Event Sub-Process** becomes initiated, and thus *Enabled* and *Running*, through the **Activity** to which it is attached. The *Event Handler* MAY only be initiated after the parent **Activity** is Running.


More than one non-interrupting *Event Handler* MAY be initiated and they MAY be initiated at different times. There might be multiple instances of the non-interrupting *Event Handler* at a time. For **Event Sub-Processes** triggered by a **Message**, the **Message** *correlation* behavior is the same as for **Receive Tasks** -- see sub clause 13.3.3. Only one interrupting Event Handler MAY be initiated for a given EventDefinition within the context of the parent **Activity**. Once the interrupting *Event Handler* is started, the parent **Activity** is interrupted and no new *Event Handlers* can be initiated or started. An **Event Sub-Process** completes when all *tokens* have reached an **End Event**, like any other **Sub-Process**. If the parent **Activity** enters the state *Completing*, it remains in that state until all contained active **Event Sub-Processes** have completed. While the parent **Activity** is in the *Completing* state, no new **Event Sub-Processes** can be initiated. If an interrupting **Event Sub-Process** is started by an *error*, then the parent **Activity** enters the state *Failing* and remains in this state until the interrupting *Event Handler* reaches a final state. During this time, the running *Event Handler* can access to the context of the parent **Activity**. However, new *Event Handlers* MUST NOT be started. Similarly, if an interrupting **Event Sub-Process** is started by a non *error* (e.g., Escalation), then the parent **Activity** enters the state *Terminating* and remains in this state until the interrupting *Event Handler* reaches a final state. During this time, the running *Event Handler* can access to the context of the parent **Activity**. However, new *Event Handlers* MUST NOT be started.


<a id="sec-13-5-5"></a>
### 13.5.5 Compensation


*Compensation* is concerned with undoing steps that were already successfully completed, because their results and possibly side effects are no longer desired and need to be reversed. If an **Activity** is still active, it cannot be compensated, but rather needs to be canceled. Cancellation in turn can result in *compensation* of already successfully completed portions of an active **Activity**, in case of a **Sub-Process**. *Compensation* is performed by a *compensation handler*. A *compensation handler* can either be a **Compensation Event Sub-Process** (for a **Sub-Process** or **Process**), or an associated **Compensation Activity** (for any **Activity**). A *compensation handler* performs the steps necessary to reverse the effects of an **Activity**. In case of a **Sub-Process**, its **Compensation Event Sub-Process** has access to **Sub-Process** data at the time of its completion (“snapshot data”). *Compensation* is triggered by a *throw* **Compensation Event**, which typically will be raised by an *error handler*, as part of cancellation, or recursively by another *compensation handler*. That **Event** specifies the **Activity** for which *compensation* is to be performed, either explicitly or implicitly.


<a id="sec-compensation-handler"></a>
#### Compensation Handler


A *compensation handler* is a set of **Activities** that are not connected to other portions of the **BPMN** model. The *compensation handler* starts with a *catch* **Compensation Event**. That *catch* **Compensation Event** either is a boundary **Event**, or, in case of a **Compensation Event Sub-Process**, the handler’s **Start Event**. A *compensation handler* connected via a boundary **Event** can only perform “black-box” *compensation* of the original **Activity**. This *compensation* is modeled with a specialized **Compensation Activity**. A **Compensation Event Sub-Process** is contained within a **Process** or **Sub-Processes**. It can access data that is part of its parent, snapshot at the point in time when its parent has completed. A *compensation* **Event Sub-Process** can in particular recursively trigger *compensation* for **Activities** contained in that its parent. It is possible to specify that a **Sub-Process** can be compensated without having to define the *compensation handler*. The **Sub-Process** attribute compensable, when set, specifies that default *compensation* is implicitly defined, which recursively compensates all successfully completed **Activities** within that **Sub-Process**, invoking them in reverse order of their forward execution.


<a id="sec-compensation-triggering"></a>
#### Compensation Triggering


*Compensation* is triggered using a *throw* **Compensation Event**, which can either be an **Intermediate** or an **End Event**. The **Activity** that needs to be compensated is referenced. If the **Activity** is clear from the context, it doesn’t have to be specified and defaults to the current **Activity**. A typical scenario for that is an inline *error handler* of a **Sub- Process** that cannot recover the *error*, and as a result would trigger *compensation* for that **Sub-Process**. If no **Activity** is specified in a “global” context, all completed **Activities** in the **Process** are compensated. By default, *compensation* is triggered synchronously, that is, the *throw* **Compensation Event** waits for the completion of the triggered *compensation handler*. Alternatively, *compensation* can just be triggered without waiting for its completion, by setting the *throw* **Compensation Event**’s waitForCompletion attribute to *false*. Multiple *instances* typically exist for **Loop** or **Multi-Instance Sub-Processes**. Each of these has its own *instance* of its **Compensation Event Sub-Process**, which has access to the specific snapshot data that was current at the time of completion of that particular *instance*. Triggering *compensation* for the **Multi-Instance Sub-Process** individually triggers *compensation* for all *instances* within the current *scope*. If *compensation* is specified via a boundary *compensation handler*, this boundary *compensation handler* also is invoked once for each *instance* of the **Multi-Instance Sub-Process** in the current *scope*.


<a id="sec-relationship-between-error-handling-and-compensation"></a>
#### Relationship between Error Handling and Compensation


*Compensation* employs a “presumed abort principle,” which has a number of consequences. First, only completed **Activities** are compensated; *compensation* of a failed **Activity** results in an empty operation. Thus, when an **Activity** fails, i.e., is left because an *error* has been thrown, it’s the *error handler’s* responsibility to ensure that no further *compensation* will be necessary once the *error handler* has completed. Second, if no *error* **Event Sub-Process** is specified for a particular **Sub-Process** and a particular *error*, the default behavior is to automatically call *compensation* for all contained **Activities** of that **Sub-Process** if that *error* occurs, thus ensuring the “presumed abort” invariant.


<a id="sec-operational-semantics"></a>
#### Operational Semantics


A **Compensation Event Sub-Process** becomes enabled when its *parent* **Activity** transitions into state *Completed*. At that time, a snapshot of the data associated with the parent **Activity** is taken and kept for later usage by the **Compensation Event Sub-Process**. In case the *parent* **Activity** is a *multi-instance* or *loop*, for each *instance* a separate data snapshot is taken, which is used when its associated **Compensation Event Sub- Process** is triggered. When *compensation* is triggered for the *parent* **Activity**, its **Compensation Event Sub-Process** is activated and runs. The original context data of the *parent* **Activity** is restored from the data snapshot. In case the *parent* **Activity** is a multi-instance or loop, for each *instance* the dedicated snapshot is restored and a dedicated **Compensation Event Sub-Process** is activated. An associated **Compensation Activity** becomes enabled when the **Activity** it is associated with transitions into state *Completed*. When *compensation* is triggered for that **Activity**, the associated **Compensation Activity** is activated. In case the **Activity** is a multi-instance or loop, the **Compensation Activity** is triggered only once, too, and thus has to compensate the effects of all *instances*.


<a id="sec-13-5-6"></a>
### 13.5.6 End Events


<a id="sec-process-level-end-events"></a>
#### Process level end events


For a “terminate” **End Event**, the **Process** is abnormally terminated—no other ongoing **Process** *instances* are affected. For all other **End Events**, the behavior associated with the **Event** type is performed, e.g., the associated **Message** is sent for a **Message End Event**, the associated signal is sent for a **Signal End Event**, and so on. The **Process** *instance* is then completed, if and only if the following two conditions hold:


- All start nodes of the **Process** have been visited. More precisely, all **Start Events** have been triggered, and for all starting **Event-Based Gateways**, one of the associated **Events** has been triggered.

- There is no *token* remaining within the **Process** *instance*.


<a id="sec-sub-process-level-end-events"></a>
#### Sub-process level end events


For a “terminate” **End Event**, the **Sub-Process** is abnormally terminated. In case of a multi-instance **Sub-Process**, only the affected *instance* is terminated—no other ongoing **Sub-Process** *instances* or higher-level **Sub-Process** or **Process** *instances* are affected. For a “cancel” **End Event**, the **Sub-Proces**s is abnormally terminated and the associated transaction is aborted. Control leaves the **Sub-Process** through a cancel intermediate boundary **Event**. For all other **End Events**, the behavior associated with the **Event** type is performed, e.g., the associated **Message** is sent for a **Message End Event**, the associated signal is sent for a signal **End Event**, and so on. The **Sub-Process** *instance* is then completed, if and only if the following two conditions hold:


- All start nodes of the **Sub-Process** have been visited. More precisely, all **Start Events** have been triggered, and for all starting **Event-Based Gateways**, one of the associated **Events** has been triggered.

- There is no *token* remaining within the **Sub-Process** *instance*.

