Перейти к основному содержимому
Версия: 7.0

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.