Создание сессий (NEWSESSION, NESTEDSESSION)
Оператор создания новой сессии позволяет выполнить действие в другой, отличной от текущей, сессии.
Как и для других операторов управления сессиями, при создании новой сессии можно явно указать вложенные локальные свойства — это позволяет перечислить, какие локальные свойства текущей сессии переносятся в новую. При создании вложенной сессии этого не требуется — она и так копирует всю текущую сессию.
Вложенные сессии
Также в платформе существует возможность создать новую вложенную сессию. В этом случае все изменения, произошедшие в текущей сессии, копируются в создаваемую вложенную сессию (это же происходит и при отмене изменений во вложенной сессии). В то же время, при применении изменений в создаваемой вложенной сессии все изменения копируются обратно в текущую сессию (при этом в базу данных они не сохраняются).
Новое SQL-соединение
По умолчанию новая сессия использует то же SQL-соединение, что и текущая. При необходимости новая сессия может быть открыта на отдельном SQL-соединении — независимом от соединения текущей сессии. Это позволяет действиям внутри неё (APPLY, чтения) выполняться независимо от транзакции текущей сессии. Это нужно, когда:
- действие, запущенное из обработчика события или потока, должно применить свои изменения независимо от того, будет ли применена или отменена текущая сессия;
- требуется прочитать актуальные зафиксированные в базе данные параллельно с длинной транзакцией текущей сессии — на отдельном соединении читатель видит зафиксированное состояние, а не снимок открытой транзакции.
На отдельном SQL-соединении новая сессия не наследует от текущей ни локальные свойства, ни изменения классов.
Опция действует, когда оператор выполняется не во время уже идущей транзакции применения текущей сессии: внутри APPLY-транзакции платформа уходит в рекурсивное применение и отдельное SQL-соединение не открывает.
Язык
Для создания действия, выполняющего другое действие в новой сессии, используется оператор NEWSESSION (для вложенных сессий используется оператор NESTEDSESSION). Открытие новой сессии на отдельном SQL-соединении задаётся опцией NEWSQL оператора NEWSESSION.
Примеры
// NEWSESSION выполняет действие в свежей сессии — изменения внешней сессии внутри не видны
isolatedRun (Currency c) {
name(c) <- 'pending'; // изменение во внешней сессии
NEWSESSION {
// здесь name(c) возвращает значение из базы, а не 'pending'
NEW c2 = Currency;
APPLY; // в базу запишется только новый Currency; name(c) останется отложенным во внешней сессии
}
}
// NESTEDSESSION наследует внешнюю сессию — применение изменений внутри копирует их обратно во внешнюю
inheritedEdit (Sku s) {
name(s) <- 'temp'; // изменение во внешней сессии
NESTEDSESSION {
// здесь видно name(s) == 'temp' из внешней сессии
name(s) <- 'final';
APPLY; // изменение копируется обратно во внешнюю сессию, в базу не пишется
}
}
// NEWSESSION NEWSQL открывает отдельное SQL-соединение, поэтому APPLY внутри идёт в собственной транзакции
backgroundLog (STRING msg) {
NEWSESSION NEWSQL {
NEW e = LogEntry {
text(e) <- msg;
time(e) <- currentDateTime();
}
APPLY; // фиксируется независимо от текущей сессии
}
}