Применение изменений (APPLY)
Оператор применения изменений сохраняет все сделанные изменения в базу, а также вызывает обработку всех синхронных глобальных событий.
Для этого оператора также можно задать применяемое действие — оно выполняется до вызова обработки событий, но внутри той же транзакции. Выполнение внутри одной транзакции повышает производительность и целостность, но и отмена изменений откатывает изменения применяемого действия вместе с остальными. Поскольку транзакция применения может автоматически повторяться после конфликта обновления, взаимной блокировки или таймаута, применяемое действие может быть выполнено более одного раза, и в нём не следует совершать необратимые внешние побочные эффекты (например, отправку писем или удаленные вызовы).
Само применение может быть отменено оператором отмены изменений, вызванным во время транзакции применения — например, внутри применяемого действия или внутри обработчика события. Результат применения отражается в свойстве System.canceled[]: TRUE, если применение было отменено, NULL иначе. После завершения операции (как удачного, так и неудачного) все сообщения, выданные в процессе применения изменений — включая сообщения от применяемого действия и от обработчиков событий — записываются в специальное свойство System.applyMessage[].
Транзакция применения атомарна: ошибка базы или нарушение ограничения также откатывают её, возвращая сессию и базу данных в состояние, предшествовавшее применению. По умолчанию транзакция использует уровень изоляции, установленный в базе данных; для отдельного применения платформа также позволяет запросить самый строгий уровень изоляции serializable, когда нужны более строгие гарантии относительно конкурирующих применений.
Как и для других операторов управления сессиями, для оператора применения изменений можно явно указать вложенные локальные свойства, которые сохранят свои изменения после выполнения оператора.
Этот оператор работает по-другому, если выполняется внутри вложенной сессии: в этом случае все изменения копируются обратно в сессию, в которую эта сессия вложена (при этом в базу данных изменения не сохраняются).
Язык
Для объявления действия, реализующего применение изменений, используется оператор APPLY.
Примеры
CLASS Sku;
id = DATA INTEGER (Sku);
in = DATA LOCAL BOOLEAN (Sku);
applyIn() {
in(Sku s) <- TRUE WHERE id(s) == 123;
APPLY NESTED (in[Sku]) {};
IF canceled() THEN
MESSAGE applyMessage();
FOR in(Sku s) DO
MESSAGE id(s); // показывает '123'
}
calculateInTransaction() {
APPLY {
id(Sku s) <- (GROUP MAX id(Sku ss)) (+) 1; // проставляем новый код внутри транзакции
}
}