Правила: сессии изменений (NEWSESSION, APPLY)
Правила сессий изменений (NEWSESSION, NESTEDSESSION, APPLY)
-
Прежде чем вводить
NEWSESSION, ассистент ОБЯЗАН решить, какое поведение сессии требуется. Ни один из вариантов ниже не работает внутри транзакцииAPPLY— в обработчике глобального события или в применяемом действии, — где сессия не создается вовсе: внутреннее действие откладывается и выполняется в текущей сессии, в той же транзакции. Ассистент НЕ ДОЛЖЕН рассчитывать там на независимую фиксацию.- изолированная независимая единица ->
NEWSESSION - изолированная единица, которая также должна видеть отдельные локальные
свойства верхней сессии ->
NEWSESSION NESTED (...) - изолированная единица, которая должна видеть все локальные свойства
верхней сессии ->
NEWSESSION NESTED LOCAL - дочерний диалог или редактор, который должен работать с несохранёнными
объектами верхней сессии и возвращать свои изменения в эту верхнюю сессию
->
NESTEDSESSION
- изолированная независимая единица ->
-
Для действий, добавленных на формы, есть два основных паттерна:
- паттерн readonly-формы: форма фактически только для просмотра, поэтому добавленные на неё действия СЛЕДУЕТ по умолчанию выполнять в новой сессии
- паттерн редактируемой формы:
форма имеет редактируемые свойства, поэтому любое добавленное на неё действие,
использующее
NEWSESSION, ДОЛЖНО либо:APPLY;IF canceled() THEN RETURN;передNEWSESSION, либо быть полностью независимым от несохранённых изменений в этой форме
-
Простой
NEWSESSION— вариант по умолчанию для изолированной работы, которая не должна случайно применить ожидающие изменения формы вызывающей стороны.Типичные паттерны в исходниках:
- readonly-списочные формы с
PROPERTIES(...) NEWSESSION NEW, EDIT, DELETE - смена статусов или создание зависимых документов
после предшествующего
APPLY - внешние или интеграционные действия, изолирующие HTTP-вызовы и сохраняющие собственные результаты
- небольшие немедленные обновления UI с
NEWSESSION { APPLY { ... } }
- readonly-списочные формы с
-
Если внутренняя логика зависит от локального состояния верхней сессии, такого как выделения, отметки или буферы импорта, ассистент ОБЯЗАН явно перенести это состояние через
NESTED (...)илиNESTED LOCALв операторе либо объявить само свойствоDATA LOCAL NESTED— такое переносится без перечисления в операторе. ПодNEWSQLне работает ни то, ни другое: на собственном соединении не переносится ничего, поэтому ассистент НЕ ДОЛЖЕН сочетатьNEWSQLс зависимостью от локального состояния верхней сессии. -
Успешный
APPLYочищает сессию, а с ней по умолчанию и всеLOCAL-свойства в ней: после возврата из такогоAPPLYобычныйLOCALснова пуст.APPLY, который не прошел или был отменен, оставляет сессию как была, вместе с локальными, — поэтому ассистент НЕ ДОЛЖЕН читатьLOCALпослеAPPLY, чтобы отличить успех от неудачи; их различаетcanceled(). Внутри вложенной сессии очистки нет вовсе: изменения копируются в родительскую сессию, а вложенная остается стоять вместе со своими локальными.Вне вложенной сессии значение
LOCALпереживает УСПЕШНЫЙAPPLY, когда выполнено ХОТЯ БЫ ОДНО из:LOCALобъявлен какNESTEDв момент объявления (LOCAL NESTED name = Type ();илиname = DATA LOCAL NESTED Type (...);), ИЛИAPPLYявно сохраняет его черезAPPLY NESTED (name1, ..., nameN)илиAPPLY NESTED LOCALдля всех локалов.
Ассистент НЕ ДОЛЖЕН рассчитывать, что значение обычного
LOCAL, вычисленное до УСПЕШНОГОAPPLY, останется доступным после него. Сохраняют его два случая: вложенная сессия, где не очищается ничего, и применение, которое не прошло или было отменено, — оно оставляет сессию как была. Если накопленное значение должно жить дольшеAPPLY— например, буфер импорта, читаемый в пост-apply доработке — ассистент ОБЯЗАН либо объявить его сNESTED, либо перечислить его вAPPLY NESTED (...)(или использоватьAPPLY NESTED LOCAL) в месте вызова. -
При использовании
NEWSESSION NESTED (...)илиNEWSESSION NESTED LOCALассистенту СЛЕДУЕТ сохранять те же вложенные локальные свойства наAPPLY, если результат должен быть скопирован обратно в верхнюю сессию, например черезAPPLY NESTED (...)илиAPPLY NESTED LOCAL. -
Ассистент НЕ ДОЛЖЕН заменять
NESTEDSESSIONпростымNEWSESSIONдля дочерних форм или диалогов, привязанных к родительскому объекту, который может быть ещё не сохранён в текущей сессии формы. -
Прежде чем открывать свежую
NEWSESSIONиз действия, запущенного на форме редактирования, ассистенту СЛЕДУЕТ решить, нужно ли сначала сохранить текущие изменения формы.Распространённый паттерн:
APPLY;IF canceled() THEN RETURN;NEWSESSION { ... }Этот паттерн используется перед сменой статусов, генерацией документов и другими изолированными последующими действиями.
-
После
APPLYассистент ОБЯЗАН проверятьcanceled()только тогда, когда последующая логика зависит от того, удалось ли сохранение — для раннего выхода, пропуска побочного эффекта или отката отложенной работы.APPLYв интерактивном контексте сам показывает пользователю сообщение об ограничении. Ассистент НЕ ДОЛЖЕН добавлятьIF canceled() THEN MESSAGE applyMessage()послеAPPLYв интерактивных действиях только для того, чтобы сообщить об ошибке — это дублирует сообщение, которое уже показала платформа. Явный вывод черезapplyMessage()илиthrowException(applyMessage())нужен только для не интерактивных вызывающих сторон (API-эндпоинты, фоновые интеграции), где никакой диалог не показывается.Если
APPLYне проходит из-за ограничения, изменения остаются несохранёнными в текущей сессии, и любой последующийAPPLYв той же сессии также не пройдёт, пока проблемные данные не исправлены или изменения не отменены (например, черезCANCEL). -
Ассистенту СЛЕДУЕТ держать блоки
NEWSESSIONнебольшими и целевыми: изолировать одну единицу работы, применить её при необходимости и выйти.Ассистент НЕ ДОЛЖЕН вводить
NEWSESSIONлишь для сокрытия багов видимости сессии. Если изменения верхней сессии должны оставаться видимыми, требуется семантика вложенной сессии. -
Тело
APPLYможет выполниться не один раз. Транзакция применения МОЖЕТ быть автоматически повторена после update conflict, deadlock или таймаута — будет ли, зависит от сбоя и от лимита попыток, — а применяемое действие и синхронные глобальные обработчики находятся внутри того, что повтор выполняет заново.Поэтому они ОБЯЗАНЫ выдерживать повтор. Необратимый внешний побочный эффект — отправка письма, вызов HTTP API, печать, запись файла — НЕ ДОЛЖЕН выполняться там: его место после успешного применения, где
canceled()говорит, состоялось ли оно.