События отмены и компенсации (Cancel and Compensation Events)

Этот раздел перенесён из документации Camunda 7 и в дальнейшем будет доработан с учётом особенностей OpenBPM Engine

События отмены (Cancel Events)

Конечное событие отмены (Cancel End Event)

Конечное событие отмены может использоваться только в сочетании с транзакционным подпроцессом. При достижении конечного события отмены выбрасывается событие отмены, которое должно быть перехвачено граничным событием отмены. Затем граничное событие отмены отменяет транзакцию и инициирует компенсацию.

Граничное событие отмены (Cancel Boundary Event)

Прикреплённое промежуточное перехватывающее событие отмены на границе транзакционного подпроцесса, или, кратко, граничное событие отмены, срабатывает при отмене транзакции. При срабатывании граничного события отмены оно сначала прерывает все активные исполнения в текущей области видимости. Затем оно запускает компенсацию всех активных граничных событий компенсации в области видимости транзакции. Компенсация выполняется синхронно, то есть граничное событие ожидает завершения компенсации, прежде чем покинуть транзакцию. По завершении компенсации транзакционный подпроцесс покидается по потоку (потокам) операций, исходящему из граничного события отмены.

cancel intermediate catch event

Примечание: для транзакционного подпроцесса допускается только одно граничное событие отмены.

Примечание: если транзакционный подпроцесс содержит вложенные подпроцессы, компенсация инициируется только для подпроцессов, завершившихся успешно.

Примечание: если граничное событие отмены размещено на транзакционном подпроцессе с характеристиками multi instance, то при инициации отмены одним экземпляром граничное событие отменяет все экземпляры.

Граничное событие отмены определяется как обычное граничное событие:

<boundaryEvent id="boundary" attachedToRef="transaction" >
  <cancelEventDefinition />
</boundaryEvent>

Поскольку граничное событие отмены всегда является прерывающим, атрибут cancelActivity не требуется.

События компенсации (Compensation Events)

Промежуточное выбрасывающее событие компенсации (Intermediate Throwing Compensation Event)

Промежуточное выбрасывающее событие компенсации может использоваться для инициации компенсации.

compensation intermediate throw event

Инициация компенсации: компенсация может быть инициирована либо для определённой активности, либо для области видимости, в которой расположено событие компенсации. Компенсация выполняется путём исполнения обработчика компенсации, связанного с активностью.

  • Когда компенсация выбрасывается для активности, связанный с ней обработчик компенсации исполняется столько же раз, сколько активность завершилась успешно.

  • Если компенсация выбрасывается для текущей области видимости, компенсируются все активности в пределах текущей области видимости, включая активности на параллельных ветках.

  • Компенсация инициируется иерархически: если компенсируемая активность является подпроцессом, компенсация инициируется для всех активностей, содержащихся внутри подпроцесса. Если подпроцесс содержит вложенные активности, компенсация выбрасывается рекурсивно. Однако компенсация не распространяется на «верхние уровни» процесса: если компенсация инициирована внутри подпроцесса, она не распространяется на активности за пределами области видимости подпроцесса. Спецификация BPMN устанавливает, что компенсация инициируется для активностей на «том же уровне подпроцесса».

  • Компенсация поглощается событийным подпроцессом компенсации: если компенсируемая активность является подпроцессом и подпроцесс содержит событийный подпроцесс, инициируемый стартовым событием компенсации, компенсация инициирует этот событийный подпроцесс вместо инициации активностей, содержащихся внутри подпроцесса.

  • Компенсация выполняется в порядке, обратном порядку исполнения. Это означает, что активность, завершившаяся последней, компенсируется первой, и так далее.

  • Промежуточное выбрасывающее событие компенсации может использоваться для компенсации транзакционных подпроцессов, завершившихся успешно.

Примечание: если компенсация выбрасывается в пределах области видимости, содержащей подпроцесс, и подпроцесс содержит активности с обработчиками компенсации, компенсация распространяется на подпроцесс только в том случае, если он завершился успешно на момент выброса компенсации. Если некоторые из активностей, вложенных в подпроцесс, завершились и имеют прикреплённые обработчики компенсации, эти обработчики компенсации не исполняются, если содержащий их подпроцесс ещё не завершён. Рассмотрим следующий пример:

compensation intermediate throw event example

В этом процессе у нас есть два параллельных исполнения: одно исполняет встроенный подпроцесс, а другое — активность «charge credit card». Предположим, что оба исполнения запущены и первое параллельное исполнение ожидает, пока пользователь завершит задачу «review bookings». Второе исполнение выполняет активность «charge credit card», и выбрасывается ошибка, из-за которой событие «cancel reservations» инициирует компенсацию. В этот момент параллельный подпроцесс ещё не завершён, что означает, что событие компенсации не распространяется на подпроцесс, и поэтому обработчик компенсации «cancel hotel reservation» не исполняется. Если User Task (и, следовательно, встроенный подпроцесс) завершается до того, как выполнится «cancel reservations», компенсация распространяется на встроенный подпроцесс.

Примечание: когда компенсация выбрасывается для активности multi instance, связанный с ней обработчик компенсации исполняется только тогда, когда все экземпляры этой активности завершились. Это означает, что активность multi instance должна завершиться, прежде чем её можно будет компенсировать.

Переменные процесса: при компенсации встроенного подпроцесса исполнение, используемое для исполнения обработчиков компенсации, имеет доступ к локальным переменным процесса подпроцесса в том состоянии, в котором они находились на момент завершения исполнения подпроцесса. Для этого делается снимок переменных процесса, связанных с исполнением области видимости (исполнением, созданным для исполнения подпроцесса). Отсюда следует несколько выводов:

  • Обработчик компенсации не имеет доступа к переменным, добавленным к параллельным исполнениям, созданным внутри области видимости подпроцесса.

  • Переменные процесса, связанные с исполнениями выше по иерархии, например переменные процесса, связанные с исполнением экземпляра процесса, не содержатся в снимке: обработчик компенсации имеет доступ к этим переменным процесса в том состоянии, в котором они находятся на момент выброса компенсации.

  • Снимок переменных делается только для встроенных подпроцессов, но не для других активностей.

Текущие ограничения:

  • waitForCompletion="false" в настоящее время не поддерживается. Когда компенсация инициируется с помощью промежуточного выбрасывающего события компенсации, событие покидается только после успешного завершения компенсации.

  • Сама компенсация в настоящее время выполняется параллельными исполнениями. Параллельные исполнения запускаются в порядке, обратном порядку завершения компенсируемых активностей. Будущие версии Camunda Automation Platform 7 могут включать опцию последовательного выполнения компенсации.

  • Компенсация не распространяется на экземпляры подпроцессов, порождённые call activity.

Промежуточное событие компенсации определяется как промежуточное выбрасывающее событие. Конкретным типом вложенного элемента в данном случае является элемент compensateEventDefinition.

<intermediateThrowEvent id="throwCompensation">
  <compensateEventDefinition />
</intermediateThrowEvent>

Кроме того, необязательный аргумент activityRef может использоваться для инициации компенсации конкретной области видимости / активности:

<intermediateThrowEvent id="throwCompensation">
  <compensateEventDefinition activityRef="bookHotel" />
</intermediateThrowEvent>

Конечное событие компенсации (Compensation End Event)

compensation end event

Конечное событие компенсации инициирует компенсацию, и текущий путь исполнения завершается. Оно имеет то же поведение и те же ограничения, что и промежуточное выбрасывающее событие компенсации.

<endEvent id="throwCompensation">
  <compensateEventDefinition />
</endEvent>

Расширения OpenBPM Engine

Атрибуты

Элементы расширений

Ограничения

Граничное событие компенсации (Compensation Boundary Event)

Прикреплённое промежуточное перехватывающее событие компенсации на границе активности, или, кратко, граничное событие компенсации, может использоваться для прикрепления обработчика компенсации к активности или встроенному подпроцессу.

compensation intermediate boundary event

Граничное событие компенсации должно ссылаться на единственный обработчик компенсации с помощью направленной ассоциации.

Граничное событие компенсации имеет иную политику активации, чем другие граничные события. Другие граничные события, такие как граничное событие сигнала, активируются при запуске активности, к которой они прикреплены. При выходе из активности они деактивируются, и соответствующая подписка на событие отменяется. Граничное событие компенсации устроено иначе. Граничное событие компенсации активируется, когда активность, к которой оно прикреплено, завершается успешно. В этот момент создаётся соответствующая подписка на события компенсации. Подписка удаляется либо при срабатывании события компенсации, либо при завершении соответствующего экземпляра процесса. Отсюда следуют такие выводы:

  • При инициации компенсации обработчик компенсации, связанный с граничным событием компенсации, вызывается столько же раз, сколько активность, к которой оно прикреплено, завершилась успешно.

  • Если граничное событие компенсации прикреплено к активности с характеристиками multiple instance, подписка на событие компенсации создаётся для каждого экземпляра.

  • Если граничное событие компенсации прикреплено к активности, содержащейся внутри цикла, подписка на событие компенсации создаётся при каждом исполнении активности.

  • При завершении экземпляра процесса подписки на события компенсации отменяются.

Граничное событие компенсации определяется как обычное граничное событие:

<boundaryEvent id="compensateBookHotelEvt" attachedToRef="bookHotel" >
  <compensateEventDefinition />
</boundaryEvent>

<association associationDirection="One" id="a1"  sourceRef="compensateBookHotelEvt" targetRef="undoBookHotel" />

<serviceTask id="undoBookHotel" isForCompensation="true" camunda:class="..." />

Поскольку граничное событие компенсации активируется после успешного завершения активности, атрибут cancelActivity не поддерживается.

Стартовое событие компенсации (Compensation Start Event)

compensation event subprocess start event

Стартовое событие компенсации может использоваться только для запуска Event Sub-Process — оно не может использоваться для запуска экземпляра процесса. Такой вид событийного подпроцесса называется событийным подпроцессом компенсации.

При деплое определения процесса с событийным подпроцессом компенсации необходимо учитывать следующее:

  • Событийный подпроцесс компенсации поддерживается только для встроенного подпроцесса, но не на уровне процесса, что обусловлено текущим ограничением: компенсация не распространяется на экземпляры подпроцессов, порождённые call activity.

  • На одном уровне подпроцесса может быть только один событийный подпроцесс компенсации.

  • Подпроцесс с событийным подпроцессом компенсации и прикреплённым граничным событием компенсации не поддерживается. Обратите внимание, что событийный подпроцесс компенсации и граничное событие компенсации имеют схожее назначение, поэтому следует выбирать только одно из них.

Событийный подпроцесс компенсации может использоваться как обработчик компенсации для встроенного подпроцесса. Подобно граничному событию компенсации, прикреплённому к подпроцессу, событийный подпроцесс компенсации вызывается выброшенным событием компенсации только в том случае, если подпроцесс ранее завершился успешно. В этом случае событийный подпроцесс компенсации вызывается столько же раз, сколько раз был завершён подпроцесс.

В отличие от граничного события компенсации, прикреплённого к подпроцессу, событийный подпроцесс компенсации поглощает выброшенное событие компенсации. Это означает, что активности, содержащиеся в подпроцессе, по умолчанию не компенсируются. Вместо этого событийный подпроцесс компенсации может рекурсивно инициировать компенсацию для активностей, содержащихся в его родителе.

compensation event subprocess

Приведённый выше процесс содержит встроенный подпроцесс с событийным подпроцессом компенсации, инициируемым стартовым событием компенсации. Обратите внимание, что данный обработчик компенсации отклоняется от компенсации по умолчанию в том, что инициирует активности компенсации в определённом порядке, не зависящем от порядка исполнения; он также содержит дополнительную активность, добавляющую логику процесса, которую невозможно вывести из тела самого подпроцесса.

XML-представление стартового события компенсации — это обычное объявление стартового события с дочерним элементом compensateEventDefinition:

<subProcess id="compensationEventSubprocess" triggeredByEvent="true">
  <startEvent id="compensationStart" >
    <compensateEventDefinition />
  </startEvent>
  <!-- ... -->
</subProcess>

Дополнительные материалы

Лицензия и атрибуция

Эта документация была создана на базе материала "Camunda 7 Docs" от Camunda, находится под лицензией Creative Commons Attribution-ShareAlike 3.0 Unported License .

Оригинал документации: https://docs.camunda.org