Сессия приложения
Contents
Сессия приложения#
Сессия приложения создается на поток прикладной бизнес логики и предоставляет доступ к сессии базы данных, EclipseLink кэшу, серверу приложения. А так же содержит необходимые инъекции зависимости для работы прикладной бизнес логики.
Сессия приложения создается:
на каждую mdi форму открытую в приложении
на rest запрос к серверу приложения
Примечание
Для ускорение rest запросов возможна настройка пула сессий
Сессия приложения не привязана к сессии базы данных. Сессия базы данных выделяется на запрос либо на транзакцию.
Каждый контроллер прикладной бизнес логики содержит контекст сессии который представляет из себя фасад для быстрого доступа к сессии приложения и стандартным языковым примитивам фреймворка.
Сессия базы данных#
Физическое соединение с базой.
Фреймворк использует механизм коротких транзакций в БД. Сессия БД выделяется для получения или изменения данных и возвращается в пул после окончания работы с данными.
Число прикладных сессий не равно числу соединений с БД.
Сессия базы данных выделяется из пула при:
Начале транзакции
Выполнении запроса из прикладного кода.
Рабочее пространство (workspace)#
Рабочее пространство содержит транзакционный кэш чтения, а так же перечень изменений для отправки в базу данных.
Рабочее пространство создается при любом действии с базой данных. Чтение, создание\удаление\обновление. И удаляется при commit или rollback.
Точки сохранения#
При создании точки сохранения, происходит сброс всех изменений из рабочего пространства в базу данных. При откате к точке сохранения, рабочее пространство удаляется.
Пользовательский сеанс#
Пользовательский сеанс начинается в момент открытия формы в новой сессии, и заканчивается при закрытии формы.
Примечание
При открытии модального окна в той же сессии, пользовательские блокировки работают в сеансе дочерней формы.
Пользовательские сеансы можно просмотреть:
Меню приложения > помощь > блокировки
Пользовательская блокировка#
Пользовательская блокировка позволяет блокировать бизнес-объект вне транзакции базы данных. Такая блокировка работает в разрезе пользовательского сеанса. Элементы заблокированного бизнес-объекта не могут быть изменены каким-либо другим пользовательским сеансом.
Пользовательскую блокировку можно снять, при этом все заблокированные сессией объекты становятся доступны для блокирования.
Подробнее можно почитать здесь.
Логические блокировки#
Логические блокировки являются транзакционными, и снимаются на commit или rollback.
Для получения блокировки используется метод Btk_LogicLockPkg.request()
,
в который передается имя блокировки.
Сессия при получении блокировки будет ожидать фиксацию или откат данных другой сессии, которая уже получила эту блокировку до этого.
Оптимистические блокировки#
По умолчанию класс использует оптимистическую блокировку, для этого
в таблице создается служебное поле nVersion_dz
.
В случае, если версия загруженного в транзакционный кэш перед изменением объекта
отличается от версии в строке таблицы базы данных при сохранении изменений,
возникает ошибка сохранения.
Преимущества оптимистической блокировки:
Не требует начало транзакции базы данных
Недостатки оптимистической блокировки:
Ошибка проявляется только при сохранении изменений в базу
В момент возникновения ошибки, сложнее отловить ее источник.Возможно появления лишней нагрузки на базу данных
От момента правки строки, до момента возникновение ошибки может пройти существенный набор действий который в итоге будет откачен.
Пессимистическая блокировка#
Транзакционная блокировка с помощью которой можно заблокировать строку базы данных. При необходимости данная блокировка может быть выполнена с помощью:
-
Совет
Смотрите Явные блокировки
OQuery c опцией
forUpdate
Btk_Pkg().lockObjects
Преимущества пессимистической блокировки
Конфликт определяется в момент выполнения блокировки
Недостатки пессимистической блокировки:
Требует транзакции базы данных
Бизнес логика#
На каждый контроллер бизнес логики создается объект в контексте сессии приложения. Таким образом бизнес логика работает в контексте сессии что позволяет:
Хранить переменные объекта в разрезе сессии
Выполнять объектные запросы в базу данных с учетом сессионного кэша
Работать в контексте транзакции сессии
Ключевые стратегии создания масштабируемого решения#
Минимизируйте количество запросов к базе данных
Для этого используйте:bulk загрузку кэша
транзакционные индексы
разделяемые классы
кэширование запросов для разделяемых классов
Ограничивайте размер транзакции
Для этого:разбивайте бизнес логику на части
К примеру разбейте массив бизнес объектов на порции для обработки.Используйте
commitwork
Это позволяет сбросить данные в базу без завершения транзакции, при этом происходит очистка оперативной памяти.
Api#
Содержит бизнес логику по обработке данных в таблице класса(сущности). Каждому классу соответствуют два файла с кодом бизнес логики данного класса:
Xxx_XxxxDpi
Содержит авто формируемый прикладной код. Данный код пересоздаётся системой формирования кода и не должен меняться разработчикамиXxx_XxxxApi
Содержит прикладной код, изменяемый разработчиками
Пример API#
class Bs_GdsCostDeviationTypeApi extends Bs_GdsCostDeviationTypeDpi[Bs_GdsCostDeviationTypeAro, Bs_GdsCostDeviationTypeApi, Bs_GdsCostDeviationTypeAta] {
override protected def entityAta: Bs_GdsCostDeviationTypeAta = Bs_GdsCostDeviationTypeAta
def register(spCode: NString
, spCaption: NString
, spDescription: NString): Unit = {
val ropSelf = get(findByMnemoCode(spCode)).getOrElse {
insert() :/ { rop =>
setsCode(rop, spCode)
rop
}
}
setsCaption(ropSelf, spCaption)
setsDescription(ropSelf, spDescription)
}
}
Pkg#
Пакеты создаются разработчиками по необходимости. Пакеты содержат методы бизнес-логики, которые не возможно отнести к какому-либо классу.
class Xxx_XxxxPkg extends Pkg{}
object Xxx_XxxxPkg extends PkgFactory[Xxx_XxxxPkg]