skip to content

In BPMN 2.0, when a loan is cancelled after its arrangement fee was charged, how do compensation markers and handlers undo that completed work?

level: seniorimportance: should knowfreq 30%

answer

  1. only completed work is undone
  2. rewind marker, outside normal flow
  3. associated activity or event sub-process
  4. thrown, then run in reverse order

basics

~20 s

In BPMN 2.0 compensation undoes activities that already completed. A handler, either a compensation activity (rewind marker) associated with the activity or a compensation event sub-process, runs only when a compensation event is thrown, in reverse order of the original flow.

solid answer

~40 s

Compensation reverses work that **completed successfully** and is no longer wanted; work still running is cancelled, not compensated. Each activity that may need undoing gets a **compensation handler**: either a **compensation activity** (marked with the rewind double triangle, `isForCompensation="true"`) connected by an **association** to a compensation boundary event on the original activity, such as "Charge arrangement fee" to "Refund fee"; or, for a sub-process, a **compensation event sub-process**, which sees a snapshot of the sub-process's data from when it completed. Handlers sit outside the normal flow and do nothing until a **throw compensation event** fires, typically on the cancellation path. If it names no activity, all completed activities in scope are compensated, in **reverse order** of their sequence flow. Compensating an activity that never completed does nothing and raises no error.

go deeper

for a junior

Recall the rewind marker and that compensation undoes work that already finished, only when a compensation event is thrown.

for a middle

Explain the two handler forms, the association from the boundary event, broadcast versus named compensation, and the reverse-order rule.

for a senior

Design compensating steps that are real business reversals, make the cancellation path throw compensation explicitly, and apply presumed abort in error handlers.

for a principal

Decide which steps need compensation at all versus manual correction, weighing the cost of maintaining reversals against how often cancellations occur.

## What compensation is for BPMN 2.0 (OMG formal/13-12-09) defines **compensation** as undoing steps that already **completed successfully**, because their results and side effects are no longer wanted. It is not rollback of work in progress: the specification says an activity that is still active cannot be compensated but must be cancelled instead (cancelling a sub-process can, in turn, compensate the parts of it that already finished). In a loan-approval process, suppose "Charge arrangement fee" and "Reserve funds" have completed when the customer cancels during the cooling-off period. Both effects are real and must be reversed: the fee refunded, the reservation released. That is compensation. ## The compensation marker and the handler A **compensation handler** is the work that reverses an activity. There are two forms: | Form | Used for | How it is attached | Data it sees | |---|---|---|---| | Compensation activity | any activity | a compensation boundary event on the original activity, linked to the handler by an **association** | treats the original as a black box | | Compensation event sub-process | a sub-process or process | contained in it, started by a compensation start event | a **snapshot** of the parent's data taken when the parent completed | Rules for the compensation activity: - It carries the **compensation marker**, a pair of left-facing triangles like a tape player's rewind button, and has `isForCompensation` set to true. - It is **outside the normal flow**: no sequence flow enters or leaves it, and it is not started when the process starts. - The compensation boundary event is not interrupting or non-interrupting; compensation can only happen after the activity finished, so there is nothing to interrupt. - The handler becomes enabled only when the original activity completes; before that there is nothing to compensate. A sub-process may also be marked **compensable** without a handler; default compensation then compensates its completed inner activities in reverse order of execution. ## How compensation is triggered 1. Something throws a **compensation event**: a compensation intermediate throw event or a compensation end event. The specification lists the typical sources as an error handler, a cancellation, or another compensation handler. 2. The event names the activity to compensate, or names none. With none, compensation is **broadcast** to all completed activities in the current sub-process, or in the whole process at the top level. 3. The handlers run in **reverse order**: if A was followed by B through a sequence flow, B is compensated before A. Instances of a loop or sequential multi-instance are compensated in reverse order of completion; parallel instances may be compensated in parallel. 4. By default the throwing event **waits** for the handlers to finish (`waitForCompletion` is true); set it to false and the flow continues immediately. For the loan: the "Customer cancels" path throws a compensation event with no activity named. "Reserve funds" completed after "Charge arrangement fee", so "Release reservation" runs first, then "Refund fee", and then the flow continues to "Close application". ## The presumed-abort rule The specification calls its principle **presumed abort**: - Only **completed** activities are compensated. Compensating an activity that failed, or that never completed, is an empty operation, and no error is raised. - When an activity fails because an error was thrown, the **error handler** is responsible for leaving nothing that still needs compensation. - If a sub-process has no error event sub-process for a particular error, the default is to compensate all its contained activities when that error occurs. ## Common mistakes - Wiring the refund into the main flow with a sequence flow. A compensation activity is reached only through compensation, never through normal flow. - Expecting every interruption of an ordinary sub-process, such as a timer, to compensate its finished work. Compensation needs a thrown compensation event; the exceptions are a transaction's cancel outcome and the presumed-abort default for an error with no error event sub-process. - Assuming a handler can see the original activity's live data. A compensation activity is black-box; only a compensation event sub-process gets the data snapshot. - Believing compensation restores state exactly. It is new business work (a refund, a reversal entry), not an undo of the database.

  • In BPMN 2.0, what happens if compensation is thrown for an activity that has not completed?
    Nothing. Under the presumed-abort principle only completed activities are compensated; compensating one that is still active, failed or never ran is an empty operation and raises no error. An active activity must be cancelled instead.
  • In BPMN 2.0, when would you use a compensation event sub-process instead of a compensation activity?
    When the undo needs the sub-process's own data, or must compensate its inner activities in a particular way. A compensation event sub-process runs with a snapshot of the sub-process's data taken at completion, and can trigger compensation of the activities inside it; a boundary-associated compensation activity only sees the activity as a black box.

saying these in an interview costs you the question

  • Compensation rolls back an activity that is still running.
  • A compensation activity is connected to the main flow with a sequence flow.
  • Compensating an activity that never completed raises an error.
  • Compensation handlers run in the same order as the original activities.
  • A compensation handler must be a sub-process; a single task cannot be one.