Требования к модели данных#
В модели данных необходимо описать события (event), которые будут обрабатываться при работе сервиса DataSpace Subscription.
Явные события в модели данных#
Явное событие может выступать как в роли самостоятельного агрегата, так и являться дочерним объектом одного из существующих агрегатов в модели — для этого у события должна быть объявлена ссылка на родительский класс (размеченная атрибутом parent=»true»). Событие, у которого отсутствует родительская ссылка, является самостоятельным агрегатом.
Данный вид событий необходимо явно создавать в составе пакета команд.
Отличия явного еvent от класса:
для него определены только операции создания и поиска;
служит только для подписки на него;
не наследуется;
имеет плоскую структуру;
допустима ссылка на родительский класс для формирования агрегатной связи;
event, у которого отсутствует родительская ссылка, является самостоятельным агрегатом;обработанный всеми подписками
eventавтоматически удаляется по истечении времени;не реплицируется в хранилище данных и не отражается в логической модели для хранилища данных.
Пример описания события, являющегося самостоятельным агрегатом:
<model model-name="MyEventDemo" version="DEV-SNAPSHOT">
<event name="MyEvent">
<property name="message" type="String"/>
</event>
</model>
Пример события, которое входит в агрегат Product:
<model model-name="ProductEventDemo" version="DEV-SNAPSHOT">
<class name="Product" label="Продукт" lockable="true">
<property name="name" type="String" label="Наименование"/>
</class>
<event name="ProductEvent">
<property name="message" type="String"/>
<property name="product" type="Product" parent="true"/>
</event>
</model>
Для свойств событий допустимыми атрибутами являются: name, type, parent, label, length, scale, mandatory, default-value.
Внимание!
При выполнении поисковых операций следует учитывать, что обработанные события по прошествии заданного времени удаляются из БД.
BaseEvent#
Любое событие наследует от абстрактного класса BaseEvent, имеющего следующие свойства:
Свойства BaseEvent:
Свойство |
Тип |
Описание |
|---|---|---|
objectId |
String (254) |
ID события |
creationTimestamp |
OffsetDateTime |
Метка времени создания события |
type |
String (254) |
Тип события (имя класса события). |
status |
enum |
Статус обработки события: |
lastChangeDate |
Date |
Время последнего изменения записи |
aggregateRootId |
String (254) |
ID корня агрегата |
ownerId |
String (254) |
ID тенанта |
partitionHash |
Long |
Предрассчитанный хеш для деления по партициям. |
Автоматические события в модели данных#
Автоматические события, в отличие от явных, не нужно создавать в пакете команд. Они создаются самим модулем DataSpace в ответ на некоторые действия, произошедшие в процессе работы модуля.
Отличия автоматического еvent от класса:
для него определена только операции поиска;
служит только для подписки на него;
не может иметь вручную объявленные свойства;
обязательна ссылка на родительский класс для формирования агрегатной связи;
обработанный всеми подписками
eventавтоматически удаляется по истечении времени;должно наследоваться от предопределенных базовых типов автоматических событий (подробно будут рассмотрены далее):
BaseChangeEvent,BaseObjectEvent,BaseTrackingEvent,BaseSnapshotEvent,BaseMergeEvent,BaseHistoryEvent;
не реплицируется в хранилище данных и не отражается в логической модели для хранилища данных.
События слияния/разъединения (BaseMergeEvent)#
Отдельным видом событий изменения являются события слияния/разъединения.
Если сконфигурировать подписку на события слияния/разъединения, то при выполнении операции слияния/разъединения сформируется событие слияния/разъединения, которое будет опубликовано в соответствии с подпиской.
Для этого в модели предметной области необходимо объявить event, унаследованный от BaseMergeEvent при помощи атрибут extends со значением BaseMergeEvent.
Этот event необходимо связать с классом, содержащим референс, обрабатываемый при слиянии/разъединении.
Внимание!
Способ объявления при помощи признака
merge-event="true"является устаревшим, пользоваться им не следует.
Такие event не доступны для создания через пакет команд или mutation GraphQL. В качестве значения тенанта (атрибут ownerId) для таких событий устанавливается значение, равное значению тенанта того агрегата, в рамках которого произошли изменения.
Для событий слияния/разъединения обязательно наличие ссылки на родительский класс, но других собственных свойств для них задать нельзя.
Пример объявления:
<model model-name="MergeEventDemo" version="DEV-SNAPSHOT">
<external-types>
<external-type type="Client" merge-kind="Organization"/>
</external-types>
<class name="Product" label="Продукт" lockable="true">
<property name="name" type="String" label="Наименование"/>
<property name="code" type="String" label="Код"/>
<reference name="client" type="Client" label="Идентификатор клиента"/>
</class>
<event name="ProductClientMergeEvent" extends="BaseMergeEvent">
<property name="product" type="Product" parent="true"/>
</event>
</model>
Собственные свойства BaseMergeEvent:
Свойство |
Тип |
Описание |
|---|---|---|
mergeKind |
String (254) |
Вид слияния — параметр процесса слияния/разъединения |
referenceName |
String (254) |
Имя обрабатываемой при слиянии ссылки |
fromReference |
String (254) |
Предыдущее значение ссылки |
toReference |
String (254) |
Новое значение ссылки |
mergeFailed |
Boolean |
Признак успешного завершения процесса слияния/разъединения («true» — если процесс завершился неудачей, «false» или «null» — если успешно) |
errorCode |
String (5) |
Код ошибки |
errorMessage |
String (254) |
Сообщение об ошибке |
События слияния/разъединения создаются автоматически сервисом DataSpace ReferenceUpdater.
Если процесс слияния/разъединения завершился успешно, то формируется event со значением поля mergeFailed = false.
Предусмотрена возможность создания события в том случае, если процесс слияния/разъединения завершился с ошибкой, требующей постороннего вмешательства.
За это отвечает настройка сервиса дедубликации duplication.service.enable-failed-merge-events. По умолчанию формирование таких событий выключено: duplication.service.enable-failed-merge-events=false.
Если перевести настройку duplication.service.enable-failed-merge-events сервиса дедубликации в значение true, то при возникновении ошибки процесса слияния/разъединения будут создаваться события со значением поля mergeFailed = true.
При этом также заполняются поля errorCode — код ошибки и errorMessage — сообщение об ошибке.
Виды ошибок, при которых формируется event со значением поля mergeFailed = true, предопределены.
Доступен вид ошибок UNIQ — ошибка нарушения уникальности.
Для подписки на неуспешные события слияния/разъединения необходимо использовать фильтр root.mergeFailed == true в поле criteria для подписки.
Примечание
Если функциональность обработки событий слияния/разъединения клиентов первый раз используется потребителем, начиная с версии компонентов DataSpace 1.11.0 и выше, и если настройка сервиса дедубликации
duplication.service.enable-failed-merge-eventsустановлена в значениеtrue, то для подписки на успешные события слияния/разъединения достаточно использовать фильтрroot.mergeFailed == falseв полеcriteriaдля подписки.Если данная функциональность использовалась до версии 1.11.0, а также если настройка сервиса дедубликации
duplication.service.enable-failed-merge-eventsустановлена в значениеtrue, то следует использовать фильтрcoalesce(root.mergeFailed, false) != trueв полеcriteriaдля подписки.
Примечание
События изменений также будут формироваться при работе сервиса дедубликации, если они отслеживают изменения дедублицируемой ссылки.
Диаграмма событийного обмена при слиянии/разъединении#
События создания записи историцирования (BaseHistoryEvent)#
Данный тип событий применим только к историцируемым сущностям (см. Историцирование).
Для них обязательно наличие ссылки на родительский класс, но других собственных свойств для них задать нельзя.
Событие формируется при создании записи в истории родительской сущности. Для родительского типа можно объявить только один event, унаследованный от BaseHistoryEvent. Пример объявления:
<model model-name="HistoryEventDemo" version="DEV-SNAPSHOT">
<class name="Account">
<property name="number" type="String" length="32" unique="true"/>
<property name="accountType" type="String" length="4" />
<property name="currency" type="String" length="3" historical="true" />
<property name="amount" type="Decimal" length="20" scale="2" historical="true"/>
</class>
<!-- создаем дочерний AccountHistoryEvent -->
<event name="AccountHistoryEvent" extends="BaseHistoryEvent">
<property name="account" type="Account" parent="true"/> <!-- Примечание: Тип `Account` историцируемый, т.к. есть историцируемые поля -->
</event>
</model>
События отслеживания изменений (BaseChangeEvent, BaseObjectEvent, BaseTrackingEvent, BaseSnapshotEvent)#
События отслеживания изменений формируются в ответ на изменения отслеживаемых классов.
Таким образом дается возможность подписаться на изменение сущностей.
Для этого в модели предметной области необходимо объявить event, указав в качестве типа parent свойства тот класс, изменения которого необходимо отслеживать и формировать события.
А также необходимо указать в атрибуте extends один из базовых, предопределенных классов событий изменения сущностей:
BaseChangeEvent;BaseObjectEvent;BaseTrackingEvent;BaseSnapshotEvent.
Для каждого из них предусмотрена своя логика формирования событий, описанная в соответствующих подразделах ниже.
Некоторые виды автоматических событий имеют только базовый набор свойств события, тогда как другие могут сохранять частичное или полное состояние сущности, получаемое в результате изменения.
В BaseChangeEvent и BaseTrackingEvent имеется возможность указать, изменения каких именно свойств необходимо отслеживать, при этом событие формируется при изменении любого из отслеживаемых свойств.
Для этого в спецификации события event используется специальный элемент parents-property.
BaseObjectEvent, BaseTrackingEvent и BaseSnapshotEvent отслеживают не только изменения, но и создание и удаление сущности.
Могут отслеживаться свойства следующих типов:
примитивные типы;
перечисления;
ссылки на другой класс (отслеживается изменение самой ссылки, а не сущности по ссылке);
reference;
свойства статусной модели (сгенерированные
statusFor<наблюдатель>);ссылки на справочники;
embeddable типы.
Свойства-коллекции указывать в качестве отслеживаемых нельзя.
Особенности обработки транзакции с созданием событий отслеживания изменений#
Для того чтобы формируемые события с сохранением состояния содержали актуальное значение всех сохраняемых свойств
все отслеживаемые сущности блокируются при выполнении пакета (кроме операций создания, т.к. это не имеет смысла).
В качестве альтернативы предусмотрена опция, позволяющая вместо блокировки выполнять повторное чтение обновленных сущностей непосредственно перед формированием события.
Данную опцию можно включить настройкой dataspace-core.events.lock-updated-entity-for-change-event — значение по умолчанию false, т.е. обновленные сущности считываются повторно.
К операциям удаления всегда применяется только блокирование.
При наличии в модели данных пользовательских событий, унаследованных от имеющихся базовых типов классов событий изменения сущности, а также при изменении соответствующих сущностей при выполнении пакета команд, в результате заданные события сформируются автоматически в той же транзакции.
Модель данных для иллюстрации примеров работы с событиями отслеживания изменений#
Далее примеры будут базироваться на следующей модели предметной области:
<?xml version="1.0" encoding="UTF-8" ?>
<model model-name="ChangeEventsModel" version="DEV-SNAPSHOT" xmlns="DataspaceModel">
<!-- Внешний тип -->
<external-types>
<external-type type="Client" merge-kind="ORGANIZATION"/>
<external-type type="Document" />
</external-types>
<!-- Корень агрегата -->
<class name="AccountGroup" label="Группа счетов клиента — агрегат">
<reference name="groupClient" type="Client" unique="true"/>
<property name="accounts" type="Account" collection="set" mappedBy="accountGroup"/>
<property name="statementInfo" type="StatementInfo" collection="set" mappedBy="accountGroup"/>
</class>
<!-- Отслеживаемая сущность для демонстрации примеров событий -->
<class name="Account" label="Клиентский счет">
<!-- Родительская ссылка на корень агрегата -->
<property name="accountGroup" type="AccountGroup" parent="true"/>
<!-- Свойство примитивного типа -->
<property name="accountType" type="String" length="4" />
<!-- Свойство примитивного типа -->
<property name="number" type="String" length="32" unique="true"/>
<!-- Embeddable свойство -->
<property name="balance" type="Balance" historical="true"/>
<!-- Ссылка на дочернюю сущность -->
<property name="statementInfo" type="StatementInfo" />
<!-- Ссылка на справочник -->
<property name="branch" type="Branch" />
<!-- Референс на внешнюю сущность -->
<reference name="client" type="Client"/>
<!-- Свойство примитивного типа Text-->
<property name="description" type="Text" />
<!-- Свойство примитивного типа Binary-->
<property name="hash" type="Binary" />
<!-- Свойство с типом enum, имя которого совпадает с именем служебного атрибута события -->
<property name="status" type="StatusEnum" mandatory="true"/>
<!-- Референс на другой агрегат -->
<reference name="product" type="Product" />
<!-- Коллекция дочерних элементов -->
<property name="postings" type="Posting" collection="set" mappedBy="account"/>
<!-- Коллекция примитивного типа -->
<property name="tags" type="String" collection="set" />
<!-- Коллекция внешних референсов -->
<reference name="documents" type="Document" collection="set"/>
<!-- <property name="statusForAccounting" type="Status"/> будет создан при генерации DataSpace на основании статусной модели -->
</class>
<!-- Enum -->
<enum name="StatusEnum">
<value name="ACTIVE"/>
<value name="INACTIVE"/>
</enum>
<!-- Embeddable -->
<class name="Balance" embeddable="true">
<property name="value" type="Decimal" length="20" scale="2"/>
<property name="currency" type="String" length="3"/>
</class>
<!-- Справочник -->
<class name="Branch" is-dictionary="true">
<property name="code" type="String" />
<property name="name" type="String" />
<property name="location" type="String"/>
</class>
<!-- Дочерний класс -->
<class name="Posting" label="Движение по счету">
<property name="account" type="Account" parent="true"/>
<property name="amount" type="Decimal" />
<property name="description" type="String" length="255"/>
</class>
<!-- Еще один дочерний класс -->
<class name="StatementInfo" label="Данные для выписки">
<property name="accountGroup" type="AccountGroup" parent="true"/>
<property name="periodicity" type="Integer" />
<property name="title" type="String" />
<property name="name" type="String" />
<property name="deliveryAddress" type="Text" />
</class>
<!-- Статусная модель -->
<status-classes class="Account">
<stakeholder name="Accounting" code="accounting" />
</status-classes>
<statuses class="Account">
<stakeholder-link code="accounting">
<status code="open" description="счет открыт без ограничений" name="открыт" initial="true">
<to status="frozen"/>
<to status="closed"/>
</status>
<status code="frozen" name="заблокирован">
<to status="open"/>
<to status="closed"/>
</status>
<status code="closed" name="закрыт"/>
</stakeholder-link>
</statuses>
<!-- Отдельный агрегат -->
<class name="Product" label="Продукт" lockable="true">
<property name="name" type="String" label="Наименование"/>
<property name="code" type="String" label="Код"/>
<reference name="client" type="Client" label="Идентификатор клиента"/>
</class>
<event name="AccountChangeEvent" extends="BaseChangeEvent">
<property name="account" type="Account" parent="true"/>
<parents-property name="statusForAccounting"/>
<parents-property name="client"/>
</event>
<event name="AccountObjectEvent" extends="BaseObjectEvent">
<property name="account" type="Account" parent="true"/>
</event>
<event name="AccountTrackingEvent" extends="BaseTrackingEvent">
<property name="account" type="Account" parent="true"/>
<parents-property name="statusForAccounting.code"/> <!-- Примечание: сохраняется code статуса, отслеживается изменения идентификатора статуса -->
<parents-property name="client"/>
<parents-property name="statementInfo"/> <!-- Примечание: сохраняется и отслеживается значение ссылки -->
<parents-property name="statementInfo.title"/> <!-- Примечание: дополнительно сохраняется значение свойства title сущности по ссылке statementInfoChildRef (если ссылка не `null`) -->
</event>
<event name="AccountSnapshotEvent" extends="BaseSnapshotEvent" snapshot-large-properties="true"> <!-- Примечание: у события задан атрибут snapshot-large-properties="true", т.е. в данных события будут сохранены значения свойств description c типом Text и hash с типом Binary-->
<property name="account" type="Account" parent="true"/>
<parents-property name="status" rename="accountStatus"/> <!-- Примечание: требуется явное переименование, поскольку status пересекается с именем служебного свойства события) -->
<parents-property name="statementInfo.title"/> <!-- Примечание: дополнительно сохраняется значение свойства title сущности по ссылке statementInfoChildRef (если ссылка не `null`) -->
</event>
</model>
Элемент parents-property#
Для указания отслеживаемых свойств существует специальный элемент в модели — parents-property со следующими атрибутами:
Имя атрибута |
Назначение |
|---|---|
name |
а) Имя отслеживаемого свойства в указанном родительском классе или |
rename |
Используется в событиях, сохраняющих состояние изменившейся сущности, если при сохранении необходимо переименовать родительское свойство или свойство сущности по ссылке (например, при коллизии имен). |
Различные варианты задания parents-property иллюстрирует пример ниже, в котором создается дочернее событие ParentsPropertiesSample, унаследованное от BaseTrackingEvent. Его элементы parents-property демонстрируют способы объявления свойств родительского класса.
<event name="ParentsPropertiesSample" extends="BaseTrackingEvent">
<property name="account" type="Account" parent="true"/>
<!-- указание на свойство-статус statusForAccounting -->
<parents-property name="statusForAccounting"/>
<!-- указание на примитивное свойство number — в результирующем классе события будет создано примитивное свойство number -->
<parents-property name="number" />
<!-- указание на ссылку на справочник branch — в результирующем классе события будет создано свойство-ссылка на справочник Branch -->
<parents-property name="branch" />
<!-- указание на примитивное свойство code справочника Branch — в результирующем классе события будет создано примитивное свойство branchCode -->
<parents-property name="branch.code" rename="branchCode" />
<!-- указание на свойство-перечисление status, переименование необходимо, поскольку имя совпадает с именем служебного свойства события — в результирующем классе события будет создано примитивное свойство accountStatus -->
<parents-property name="status" rename="accountStatus" />
<!-- указание на свойство-reference product — в результирующем классе события будет создано свойство-reference -->
<parents-property name="product" />
<!-- указание на embeddable-свойство balance целиком — в результирующем классе события свойства будет создано такое же embeddable свойство -->
<parents-property name="balance" />
<!-- указание на примитивное поле value у свойства balance с типом embeddable — в результирующем классе события будет создано примитивное свойство value -->
<parents-property name="balance.value" />
<!-- указание на свойство-ссылку statementInfo — в результирующем классе события будет создано свойство-ссылка -->
<parents-property name="statementInfo" />
<!-- указание на примитивное свойство name у свойства statementInfo — в результирующем классе события будет создано примитивное свойство infoName -->
<parents-property name="statementInfo.name" rename="infoName" />
</event>
BaseChangeEvent#
При объявлении для сущности дочернего события, унаследованного от BaseChangeEvent, событие указанного типа будет формироваться при изменении любого из свойств сущности из списка parents-property (и только в этом случае).
Значения свойств отслеживаемой сущности в данных события не сохраняются, элементы parents-property задаются только для отслеживания изменений.
Собственные свойства BaseChangeEvent:
Свойство |
Тип |
Описание |
|---|---|---|
sysVersion |
Long |
Версия сущности (ее агрегата) по результатам операции |
sysTimeChanged |
OffsetDateTime |
Метка времени изменения, одинакова для всех событий в транзакции и совпадает с меткой времени изменения агрегата |
Пример объявления BaseChangeEvent события, формируемого при изменении любого из свойств statusForAccounting, product:
<event name="AccountChangeEvent" extends="BaseChangeEvent">
<property name="account" type="Account" parent="true"/>
<parents-property name="statusForAccounting"/>
<parents-property name="product"/>
</event>
BaseObjectEvent#
При объявлении для сущности дочернего события, унаследованного от BaseObjectEvent, событие указанного типа будет формироваться при изменении любого из свойств сущности (включая изменение коллекций примитивов и референсов), а также создании и удалении объекта.
Эти события не хранят состояния отслеживаемой сущности. Для данного типа запрещено явное указание элементов parents-property, т.к. это не несет смысла.
Внимание!
Коллекции ссылок с типом связи «один-ко-многим» и mapped-by ссылки с типом связи один-к-одному не отслеживаются ни одним из типов событий.
Внимание!
При использовании данного вида события следует учитывать особенности отслеживания изменений сущностей при выполнении пакета команд Packet (см. раздел «Особенности отслеживания изменений сущностей при выполнении пакета команд Packet» документа «Руководство прикладного разработчика»).
В модели данных может быть только одно событие BaseObjectEvent для каждого пользовательского типа.
Собственные свойства BaseObjectEvent:
Свойство |
Тип |
Описание |
|---|---|---|
sysVersion |
Long |
Версия сущности (ее агрегата) по результатам операции |
sysTimeChanged |
OffsetDateTime |
Метка времени изменения. Одинакова для всех событий в транзакции и совпадает с меткой времени изменения агрегата |
sysObjectEvent |
enum SysObjectEvent |
Тип действия, совершенного над отслеживаемой сущностью: |
Пример объявления BaseObjectEvent события, формируемого при изменении любого из свойств родительского класса Account, кроме postings,
при создании и удалении объектов типа Account.
<event name="AccountObjectEvent" extends="BaseObjectEvent">
<property name="account" type="Account" parent="true"/>
</event>
BaseTrackingEvent#
При объявлении для сущности дочернего события, унаследованного от BaseTrackingEvent, событие указанного типа будет формироваться при изменении любого из перечисленных в parents-property свойств сущности, а также создании и удалении объекта.
Значения указанных при помощи элементов parents-property свойств родительской сущности по состоянию на момент завершения операции сохраняются в копии этих свойств в данных события. При удалении сущности сохраняются значения, которые эти свойства имели непосредственно перед удалением.
Доступна возможность сохранения свойств сущностей по ссылке, а также переименования сохраняемых свойств.
Внимание!
Элементы
parents-propertyтиповBaseTrackingEventне могут указывать на коллекционные свойства.
Собственные свойства BaseTrackingEvent:
Свойство |
Тип |
Описание |
|---|---|---|
sysVersion |
Long |
Версия сущности (ее агрегата) по результатам операции |
sysTimeChanged |
OffsetDateTime |
Метка времени изменения. Одинакова для всех событий в транзакции и совпадает с меткой времени изменения агрегата |
sysObjectEvent |
enum SysObjectEvent |
Тип действия, совершенного над отслеживаемой сущностью: |
sysChangeUser |
String |
Информация о пользователе, изменившем данные, используется значение из HTTP-заголовка (конфигурирование способа получения информации описано в разделе «Способы получения информации о пользователе» документа «Руководство по системному администрированию») |
При изменении атрибутного состава родительского класса (например, в родительском классе добавили или удалили атрибут, или изменили тип, или изменился признак deprecated) класс события также обновится соответствующим образом.
Пример объявления BaseTrackingEvent события, формируемого при изменении любого из свойств statusForAccounting, description, statementInfo, а также при создании и удалении объектов:
<event name="AccountTrackingEvent" extends="BaseTrackingEvent">
<property name="account" type="Account" parent="true"/>
<!-- Сохраняется code статуса, отслеживается изменения идентификатора статуса -->
<parents-property name="statusForAccounting.code"/>
<parents-property name="description"/>
<!-- Сохраняется и отслеживается значение ссылки -->
<parents-property name="statementInfo"/>
<!-- Дополнительно сохраняется значение свойства сущности по ссылке (если ссылка не `null`) -->
<parents-property name="statementInfo.title"/>
</event>
BaseSnapshotEvent#
При объявлении для сущности дочернего события, унаследованного от BaseSnapshotEvent, событие указанного типа будет формироваться при изменении любого из свойств сущности (включая изменение коллекций примитивов и референсов), а также создании и удалении объекта.
Это событие сохраняет в своих данных состояние всех свойств по состоянию на момент завершения операции, за исключением коллекций и свойств с типами Text и Binary (то есть в классе события будут созданы соответствующие свойства).
При удалении сущности сохраняются значения, которые эти свойства имели непосредственно перед удалением.
Помимо этого, через элементы parents-property доступна возможность сохранения свойств сущностей по ссылке, а также переименования сохраняемых свойств.
Если необходимо сохранять и свойства с типами Text и Binary, то следует явно указать имена нужных свойств при помощи элемента parents-property.
Также имеется возможность сохранять значения всех свойств с типами Text и Binary, задав на элементе event события атрибут snapshot-large-properties="true".
Внимание!
Элементы
parents-propertyтиповBaseSnapshotEventне могут указывать на коллекционные свойства.
Внимание!
Следует учесть, что данные свойств с типами
TextиBinaryмогут занимать значительное место. Поэтому в событии следует сохранять только то, что действительно необходимо фиксировать на момент транзакции (что нельзя, например, получить при помощи GraphQL-query при публикации).
Внимание!
При использовании данного вида события следует учитывать особенности отслеживания изменений сущностей при выполнении пакета команд Packet (см. раздел «Особенности отслеживания изменений сущностей при выполнении пакета команд Packet» документа «Руководство прикладного разработчика»).
Состав собственных атрибутов BaseSnapshotEvent совпадает с BaseTrackingEvent.
При изменении атрибутного состава родительского класса (например, в родительском классе добавили или удалили атрибут, или изменили тип, или изменился признак deprecated) класс события также соответствующим образом изменится.
Пример объявления BaseSnapshotEvent события, формируемого при изменении любого из свойств parent класса, кроме postings, а также при создании и удалении объектов:
<event name="AccountSnapshotEvent" extends="BaseSnapshotEvent" snapshot-large-properties="true"> <!-- Примечание: включен snapshot-large-properties, т.е. сохраняются и свойства `someText`, `someBinary` -->
<property name="account" type="Account" parent="true"/>
<!-- Дополнительно сохраняется значение свойства сущности по ссылке (если ссылка не `null`) -->
<parents-property name="statementInfo.title"/>
<!-- Необходимо явное переименование, поскольку status пересекается с именем служебного свойства события) -->
<parents-property name="status" rename="accountStatus"/>
</event>
Отслеживание состояния очереди подписок#
Для отслеживания состояния очереди подписок необходимо воспользоваться функционалом пользовательских sql запросов и
сформировать в своей модели необходимые запросы к таблице очереди обработки событий t_dspc_sys_event_queue_item.
Примеры таких запросов можно найти в разделе «Примеры запросов для контроля очереди событий модуля подписок».