Сессия приложения#

Сессия приложения создается на поток прикладной бизнес логики и предоставляет доступ к сессии базы данных, EclipseLink кэшу, серверу приложения. А так же содержит необходимые инъекции зависимости для работы прикладной бизнес логики.

Сессия приложения создается:

  • на каждую mdi форму открытую в приложении

  • на rest запрос к серверу приложения

    Примечание

    Для ускорение rest запросов возможна настройка пула сессий

Сессия приложения не привязана к сессии базы данных. Сессия базы данных выделяется на запрос либо на транзакцию.

Каждый контроллер прикладной бизнес логики содержит контекст сессии который представляет из себя фасад для быстрого доступа к сессии приложения и стандартным языковым примитивам фреймворка.

Сессия базы данных#

Физическое соединение с базой.

Фреймворк использует механизм коротких транзакций в БД. Сессия БД выделяется для получения или изменения данных и возвращается в пул после окончания работы с данными.

Число прикладных сессий не равно числу соединений с БД.

Сессия базы данных выделяется из пула при:

  • Начале транзакции

  • Выполнении запроса из прикладного кода.

Рабочее пространство (workspace)#

Рабочее пространство содержит транзакционный кэш чтения, а так же перечень изменений для отправки в базу данных.

Рабочее пространство создается при любом действии с базой данных. Чтение, создание\удаление\обновление. И удаляется при commit или rollback.

Точки сохранения#

При создании точки сохранения, происходит сброс всех изменений из рабочего пространства в базу данных. При откате к точке сохранения, рабочее пространство удаляется.

Пользовательский сеанс#

Пользовательский сеанс начинается в момент открытия формы в новой сессии, и заканчивается при закрытии формы.

Примечание

При открытии модального окна в той же сессии, пользовательские блокировки работают в сеансе дочерней формы.

Пользовательские сеансы можно просмотреть: Меню приложения > помощь > блокировки

Пользовательская блокировка#

Пользовательская блокировка позволяет блокировать бизнес-объект вне транзакции базы данных. Такая блокировка работает в разрезе пользовательского сеанса. Элементы заблокированного бизнес-объекта не могут быть изменены каким-либо другим пользовательским сеансом.

Пользовательскую блокировку можно снять, при этом все заблокированные сессией объекты становятся доступны для блокирования.

Подробнее можно почитать здесь.

Логические блокировки#

Логические блокировки являются транзакционными, и снимаются на commit или rollback.

Для получения блокировки используется метод Btk_LogicLockPkg.request(), в который передается имя блокировки.

Сессия при получении блокировки будет ожидать фиксацию или откат данных другой сессии, которая уже получила эту блокировку до этого.

Оптимистические блокировки#

По умолчанию класс использует оптимистическую блокировку, для этого в таблице создается служебное поле nVersion_dz. В случае, если версия загруженного в транзакционный кэш перед изменением объекта отличается от версии в строке таблицы базы данных при сохранении изменений, возникает ошибка сохранения.

Преимущества оптимистической блокировки:

  • Не требует начало транзакции базы данных

Недостатки оптимистической блокировки:

  • Ошибка проявляется только при сохранении изменений в базу
    В момент возникновения ошибки, сложнее отловить ее источник.

  • Возможно появления лишней нагрузки на базу данных
    От момента правки строки, до момента возникновение ошибки может пройти существенный набор действий который в итоге будет откачен.

Пессимистическая блокировка#

Транзакционная блокировка с помощью которой можно заблокировать строку базы данных. При необходимости данная блокировка может быть выполнена с помощью:

Преимущества пессимистической блокировки

  • Конфликт определяется в момент выполнения блокировки

Недостатки пессимистической блокировки:

  • Требует транзакции базы данных

Бизнес логика#

На каждый контроллер бизнес логики создается объект в контексте сессии приложения. Таким образом бизнес логика работает в контексте сессии что позволяет:

  • Хранить переменные объекта в разрезе сессии

  • Выполнять объектные запросы в базу данных с учетом сессионного кэша

  • Работать в контексте транзакции сессии

Ключевые стратегии создания масштабируемого решения#

  1. Минимизируйте количество запросов к базе данных
    Для этого используйте:

    • bulk загрузку кэша

    • транзакционные индексы

    • разделяемые классы

    • кэширование запросов для разделяемых классов

  2. Ограничивайте размер транзакции
    Для этого:

    • разбивайте бизнес логику на части
      К примеру разбейте массив бизнес объектов на порции для обработки.

    • Используйте 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]