Компенсация подразумевает возврат к исходной точке цепочки успешно выполненных действий по причине того, что результат этих действий или побочные эффекты больше не представляют ценности и должны быть отменены. Компенсации не происходит в случае, если Действие ещё запущено; в данном случае оно должно быть отменено. Отмена, в свою очередь, может привести к компенсации успешно выполненных операций в составе действия (например, в Подпроцессе).
Компенсация выполняется при помощи обработчика компенсации, который выполняет шаги, необходимые для отмены результатов Действия. В Подпроцессе обработчик компенсации имеет доступ к данным этого Подпроцесса в момент его завершения, т.е. делает моментальный снимок набора данных Подпроцесса («snapshot data»).
Компенсация запускается инициирующим триггер Событием Компенсация, вызываемым обычно обработчиком ошибок (если Событие является частью процедуры отмены Действия) либо другим обработчиком компенсации, что происходит реже. Такое Событие определяет Действие, которое будет компенсировано (скрыто или явно).
Обработчик компенсации представляет собой набор Действий, не соединенных с остальными частями модели Процесса. Начальной точкой обработчика компенсации является обрабатывающее триггер Событие Компенсация. Такое Событие либо присоединено к границе Действия, либо является Стартовым событием данного обработчика (например, в Событийном подпроцессе Компенсация).
Обработчик компенсации, присоединенный к Действию посредством расположенного на его границе События, может производить компенсацию Действия лишь по типу «черного ящика». Такой вид компенсации создается при помощи особого Действия Компенсация, присоединенного к Событию на границе Действия посредством Ассоциации (см. фигуру 10.121). Графический элемент Действия Компенсация (Задача или Подпроцесс) имеет внутренний маркер, указывающий на то, что данное Действие является компенсацией и находится за пределами Стандартного потока операций Процесса.
Фигура 10.121 – Компенсация, использующая Событие на границе Действия
Событийный Подпроцесс Компенсация находится внутри Процесса или Подпроцесса (см. фигуру 10.122). Как и Действие Компенсация, Событийный Подпроцесс Компенсация находится за пределами Стандартного потока операций Процесса. Если граница графического элемента такого Подпроцесса выполнена пунктиром, это означает, что Подпроцесс имеет доступ к данным родительского Процесса, т.е. делает моментальный снимок набора данных Процесса в момент его завершения («snapshot data»). Событийный Подпроцесс Компенсация может время от времени вызывать компенсацию Действий в составе родительского Процесса.
Фигура 10.122 – Обзор диаграммы класса
При необходимости можно указать, что Подпроцесс может быть компенсирован без предварительного указания обработчика компенсации. В случае, если значение атрибута compensable Подпроцесса указано, это означает, что указана и компенсация по умолчанию (т.е. время от времени производится компенсация всех успешно выполненных Действий Подпроцесса).
На фигуре 10.122 отображен заказной Событийный подпроцесс Компенсация, вызываемый Стартовым событием Компенсация. Обратите внимание, что данный обработчик компенсации отличается от компенсации, установленной по умолчанию, тем, что выполняет Действия Компенсация в порядке, отличном от порядка в следующем примере. Он также содержит дополнительное Действие, дополняющее логику Процесса, которое не может выводиться из самого Подпроцесса.
Запуск компенсации осуществляется посредством инициириующего компенсацию События, как Промежуточного, так и Конечного. Оно ссылается на Действие, компенсацию которого необходимо произвести. Если же из контекста ясно, какое Действие будет компенсировано, указывать ссылку не обязательно, – Событие относится к текущему Действию. Стандартным сценарием запуска компенсации является ситуация, в которой строчный обработчик возникающих в Подпроцессе ошибок не может устранить ошибку, в результате чего запускается компенсация данного Подпроцесса. Если в общем контексте не указано ни одного предназначенного для компенсации Действия, все Действия Подпроцесса будут компенсированы.
По умолчанию, компенсация запускается синхронно. Это означает, что инициириующее компенсацию Событие будет ожидать завершения работы запущенного обработчика компенсации. Компенсация также может быть запущена вне зависимости от того, завершилась ли работа обработчика компенсации или нет. Для этого атрибут waitForCompletion События должен иметь значение «false».
Множественные экземпляры обычно используются в Циклах и Многоэкземплярных Подпроцессах. Каждый из них имеет свой собственныйэкземпляр Событийного Подпроцесса Компенсация, имеющего доступ к определенным данным Подпроцесса, которые были актуальными на время выполнения каждого из экземпляров. Запуск компенсации Многоэкземплярного Подпроцесса в индивидуальном порядке инициирует осуществление компенсации всех экземпляров данного Подпроцесса в рамках контекста. В случае, если указано, что компенсация должна быть выполнена посредством обработчика компенсации, расположенного на границе Подпроцесса, такой обработчик также запускается для каждого экземпляра этого Подпроцесса в рамках контекста.
Следующее описание содержит информацию о том, как взаимодействуют обработчик событий и компенсация:
Дорожка представляет собой подразделение внутри Процесса (как правило, внутри Пула) и простирается на всю длину данного Процесса как горизонтально (см. фигуру 10.124), так и вертикально (см. фигуру 10.123). По желанию разработчика модели, текст, относящийся к Дорожке (например, название Дорожки или атрибут какого-либо элемента Процесса), может быть помещен в любом месте данной Дорожки и располагаться в любом направлении. В представленных ниже примерах название Дорожки располагается в виде баннера в левой части (в горизонтальном Пуле) или вверху (ввертикальном Пуле) рядом с линией, отделяющей название Дорожки от названия Пула. Однако такое размещение текста не является обязательным.
Фигура 10.123 – Пул, содержащий две вертикальные Дорожки
Фигура 10.124 – Пул, содержащий две горизонтальные Дорожки
Дорожки используются для организации и категоризации Действий, расположенных внутри Пула. Содержание Дорожек зависит от разработчика модели. Спецификация BPMN не указывает на то, какую функцию в Процессе должны выполнять Дорожки, которые часто используются в качестве внутренних ролей (например, Менеджер, Партнер), систем (например, прикладные системы предприятия), внутренних отделов (например, поставки, бюджет) и т.д. Также Дорожки могут быть вложены (см. фигуру 10.125) или установлены в матрице. Например, может существовать внешнее множество Дорожек отделов предприятия, а также внутреннее множество Дорожек для ролей, существующих внутри каждого отдела.
Фигура 10.126 – отображение диаграммы класса Lane. Указанная Дорожка содержится в элементе LaneSet Процесса.
Фигура 10.127 – Диаграмма классов элемента Lane
Посредством элемента LaneSet определяется контейнер для одной или более Дорожек. В Процессе могут содержаться один или несколько элементов LaneSet, каждый из которых (а также его Дорожка) могут по-другому разбивать узлы Потока операций.
Элемент LaneSet наследует атрибуты и ассоциации элемента BaseElement (см. таблицу 8.5). Таблица 10.134 содержит информацию о дополнительных атрибутах и ассоциациях элемента LaneSet.
Таблица 10.134 Атрибуты и ассоциации элемента LaneSet
Название атрибута |
Описание/использование |
name: sting [0..1] |
Название LaneSet. На диаграмме BPMN элемент LaneSet не отображается, поэтому его название также не отображается на ней. |
process: Process |
Процесс, содержащий данный элемент LaneSet. |
lanes: Lane [0..*] |
Одно или более подразделений внутри графического элемента Дорожка, определяющие характерное для данного LaneSet разделение. |
parentLane: Lane [0..1] |
Ссылка на Дорожку, являющуюся родительской для данного LaneSet. The reference to a Lane element which is the parent of this LaneSet. |
Отдельно взятый графический элемент Дорожка является одним подразделением элемента LaneSet и может определять разделительный элемент, который, в свою очередь, определяет значение и тип элемента. Посредством разделительного элемента может указываться список узлов Потока операций, которые необходимо разделить внутри Дорожки. Все Доржки одного LaneSet ДОЛЖНЫ указывать разделительный элемент одного и того же типа (к примеру, все Дорожки одного LaneSet ссылаются на Ресурс в качестве разделительного элемента, однако, каждая Дорожка сслыается на отдельный экземпляр Ресурса).
Элемент Lane наследует атрибуты и ассоциации элемента BaseElement (см. таблицу 8.5). Таблица 10.135 содержит информацию о дополнительных атрибутах и ассоциациях элемента Lane.
Таблица 10.135 Атрибуты и ассоциации элемента Lane
Название атрибута |
Описание/использование |
name: string |
Название Дорожки. |
partitionElement: BaseElement [0..1] |
Ссылка на элемент BaseElement, указывающая на значение и тип разделения. Посредством данного разделительного элемента в BPMN могут указываться элементы FlowElement, которые необходимо разделить внутри данной Доржки. |
partitionElementRef: BaseElement [0..1] |
Ссылка на элемент BaseElement, указывающая на значение и тип разделения. Посредством данного разделительного элемента в BPMN могут указываться элементы FlowElement, которые необходимо разделить внутри данной Доржки. |
childLaneSet: LaneSet [0..1] |
Ссылка на элемент LaneSet для вложенных Дорожек. |
flowNodeRefs: FlowNode [0..*] |
Список элементов FlowNode, которые необходимо разделить в Дорожке в соответствии со значением элемента partitionElement, являющегося частью элемента Lane. |