Brief: сессии изменений
Что такое сессия
Сессия изменений — место, где изменения накапливаются локально, а не пишутся в базу сразу. В нее попадают изменения первичных свойств, в том числе локальных, и изменения классов объектов — созданные и удаленные объекты, CHANGECLASS. Пока изменения не применены, они остаются в этой сессии; что из них увидит другая сессия, решают вместе открывающий ее оператор — NESTEDSESSION показывает все изменения верхней сессии, NEWSESSION читает из базы, перенося локальные свойства, названные его NESTED — списком в скобках либо все сразу через NESTED LOCAL, — изменения классов, если задан CLASSES, и, перечислено оно или нет, всё объявленное DATA LOCAL NESTED, — и объявления самих свойств, ведь объявленное DATA LOCAL NESTED переносится само; текущую сессию действию задает контекст выполнения — сессия формы, сессия вызывающего действия либо сессия, переданная платформой.
Значение свойства на начало сессии возвращает оператор PREV, а производные от него операторы изменений SET, DROPPED, CHANGED, SETCHANGED, DROPCHANGED, SETDROPPED отвечают, что именно изменилось в сессии.
Аналогия: незафиксированная транзакция базы данных, живущая все время работы пользователя с формой.
NEWSESSION и NESTEDSESSION
Оператор NEWSESSION выполняет вложенное действие в отдельной сессии, изолированной от текущей; оператор NESTEDSESSION — во вложенной, которая копирует в себя изменения текущей сессии, а применение внутри нее возвращает изменения обратно. Если любой из этих операторов выполняется во время транзакции применения текущей сессии, в этот момент сессия не создается — вложенное действие откладывается и выполняется в текущей сессии внутри той же транзакции.
NEWSESSION [NEWSQL] [FORMS formId1, ..., formIdM] [NESTED [nestedPropertySelector] [CLASSES]] [SINGLE] action
NESTEDSESSION [SINGLE] action
Опция NESTED перечисляет переносимые локальные свойства, NEWSQL открывает сессию на отдельном SQL-соединении. Они взаимоисключающи: написанные вместе, они разберутся, но победит NEWSQL, а вся клауза NESTED будет проигнорирована.
К новой сессии обращаются, когда действие — отдельная единица работы: диалог, импорт, обработка файла, фоновая запись.
logError (STRING message) {
NEWSESSION NEWSQL {
NEW e = LogEntry { text(e) <- message; }
APPLY;
}
}
APPLY и CANCEL
Оператор APPLY применяет изменения — записывает накопленное в базу, выполняя по дороге обработки глобальных событий и проверки ограничений. Во вложенной сессии он не пишет в базу ничего: изменения копируются обратно в сессию, в которую вложена эта. Оператор CANCEL отменяет изменения — очищает сессию, кроме случая внутри транзакции применения, где он вместо этого отменяет выполняющийся APPLY.
APPLY [NESTED [nestedPropertySelector] [CLASSES]] [SINGLE] [SERIALIZABLE] [action]
CANCEL [NESTED [nestedPropertySelector] [CLASSES]]
Итог применения читается из свойств System.canceled[] и System.applyMessage[].
Аналогия: COMMIT и ROLLBACK.
Видимость изменений между сессиями
Вне транзакции применения то, что видит новая сессия, задают вместе создавший ее оператор и объявления самих свойств, между двумя краями: сессия, наследующая непримененные изменения верхней, и сессия, которая их не видит и читает зафиксированное состояние базы. Это не переключатель — NESTED (...) переносит перечисленные локальные свойства, а CLASSES независимо переносит изменения классов, так что унаследовать можно и часть состояния.
Оператор — не единственное место, где это решается. Свойство, объявленное DATA LOCAL NESTED, переносится само, без перечисления в операторе, а MANAGESESSION / NOMANAGESESSION в этом объявлении сужают перенос до APPLY / CANCEL или до NEWSESSION соответственно (DATA, NEWSESSION).
NESTEDSESSION — один край: видны все изменения верхней сессии. NEWSESSION — другой: свойства читаются из базы, кроме объявленных DATA LOCAL NESTED — те переносятся сами, — а опции NESTED и CLASSES расширяют перенос. NEWSQL, наоборот, сужает его: на собственном соединении не переносится ничего, объявлено NESTED или нет.
Что дает каждое сочетание, описано в создании сессий и в операторе NEWSESSION.