Синхронизация расчетов и изменений
В базах данных ДП АСУТП часто выполняемой операцией является расчет агрегированных значений; например, определение максимального значения из множества или расчет мгновенного расхода жидкости или газа, используя оперативные данные о давлении, его перепаде на диафрагме и температуре, а также ряд заданных нормативных поправочных коэффициентов. В модели мы можем отобразить это, установив ассоциацию один-ко-многим (часто соответствующей отношению контейнер-элемент) и использовав класс-ассоциацию Multiplexer (в который заложена логика преобразования нескольких исходных значений в одно производное). Объекты-элементы являются источниками данных для своего контейнера, в свою очередь, некоторая подсистема опроса систем автоматики является источником оперативных данных для них самих. Эти взаимосвязи можно показать, используя диаграмму классов UML (см. рис. 2).

Рис. 2. Типовые отношения классов БД ДП АСУТП.
В системе, управляемой событиями, при изменении хотя бы одного из значений, участвующих в расчете результата и хранящихся в объектах-элементах, должен происходить пересчет формулы и запись нового расчетного значения в объект-контейнер. Рассмотрим для примера расчет некоторого состояния по двум исходным логическим сигналам “открыт”, “закрыт” (см. рис. 3).

Рис. 3. Вариант алгоритма перерасчета агрегированного значения.
В рассмотренном алгоритме есть упущение – перерасчет результата происходит при поступлении первого же из изменений. В случае, когда произошло изменение обоих значений, выполнение промежуточного расчета формулы агрегирования с использованием одного нового и одного устаревшего значения избыточно, и, скорее всего, ошибочно. При этом мы не можем заранее утверждать, что всегда при поступлении нового значения одного из сигналов поступает и новое значение другого. Т.о., мы приходим к требованию отслеживать режим поступления обновлений. Для решения этой задачи можно предложить блокировать источником данных передачу сообщений об изменении значений в объектах-элементах на период записи всего множества поступивших обновленных значений.
Тогда события об изменении поступят в класс-контейнер после записи обеих новых значений и расчет будет выполнен два раза, но с актуальными данными. (Будучи уверенным, что при поступлении первого же из извещений актуальны оба значения, можно сократить количество перерасчетов до одного).
Однако проблема остается, если источник данных – не один объект, а множество, и на диаграмме мы рассматриваем связь “многие-ко-многим”. (Задача часто возникает при реализации субъектно-ориентированного подхода к проектированию базы данных ДП АСУТП, при котором вводится множество классов, содержащих наборы нормативно-справочных данных, описывающие один и тот же производственный объект при различных точках зрения (принципах декомпозиции предметной области), но которым требуется разделять оперативные данные о его состоянии). Передача (копирование) данных из источников получателям приводит к необходимости поддержания целостности.
Здесь мы приходим к классической ситуации введения аспекта – реализация в отдельном классе-источнике или получателе данных алгоритма отслеживания взаимодействия других пар объектов и синхронизации с ними исключительно затруднена. Цель – обеспечить синхронизацию обновления данных; желаемое поведение аспекта – реализовать “конвейерную передачу” обновлений по уровням иерархии и между поддеревьями БД.

Сначала определим “точку пересечения”. Она одна – аспект перехватывает управление при попытке выполнения каким-либо из объектов-источников записи одного или нескольких новых значений; блокирует обработку новых значений в объектах-получателях, дает завершиться перехваченным методам SetValue(…), после чего ожидает в течение заданного интервала времени выполнения аналогичных действий другими объектами-источниками (см. рис. 4). По истечении времени ожидания происходит разблокирование всех объектов-получателей, в которые были записаны новые значения. Данная логика показана на рис. 5; отношение “многие-ко-многим” классов-источников и получателей данных рассматривается как множество отношений “один-ко-многим” их экземпляров. (Мы рассматриваем множества объектов – экземпляров некоторых классов, объединенные в две группы по их роли в частном информационном взаимодействии: источников и получателей данных; стереотипы “source” и “receiver” являются производными от базового “group”.
Имена групп ( при отличии стереотипа) совпадают, что подчеркивает единообразие входящих в них классов).

Отметим, что не требуется вводить точку пересечения с классом-получателем данных, поскольку нет необходимости перехватывать все выполняемые вызовы изменения данных в нем, а также использование стереотипа “around” для метода OnSetValue() аспектного класса: часть служебных операций выполняется до исполнения вызова SetValue(…), часть – после. Предложенное решение все еще содержит ряд недостатков: объект-источник зависим от реализации объекта-получателя; введение периодов ожидания плохо согласуется с событийной моделью; объект-получатель должен проверять попадание разности нового и предыдущего значений в “зону нечувствительности”; его структура усложняется средствами поддержки блокировок. Можно предложить вариант, свободный и от данных недостатков.
Для этого определим, что у каждой группы есть менеджер – экземпляр аспектного класса, выполняющий контракты каждого из классов группы, в т.ч. и вызов метода SetValue(…) для записи измененного значения в класс-получатель. Это позволяет также выполнять операции блокирования/разблокирования только по отношению к этому аспектному классу. На него же может быть переложено выполнение проверки “существенности” отличия нового значения от текущего в объекте. Тогда желаемое поведение, реализующее транзакционный подход к передаче массива данных, можно отобразить в виде :диаграммы (см. рис. 6). (На диаграмме показано взаимодействие только двух групп, хотя, разумеется, объекты и даже единственный объект группы-источника может являться записывать данные в несколько объектов, в т.ч. принадлежащих различным группам.) Поскольку, как отмечалось выше, каждая из групп может играть роль как источника, так и получателя данных, то на диаграмме классов достаточно показать связь аспекта и одной группы (см. рис. 7а).
Диаграмма, показывающая внутреннюю логику аспекта при разблокировании, приведена на рис. 7б.Отметим, что возможно одновременная блокировка группы несколькими менеджерами групп-источников: запись различных данных в один и тот же объект в любом случае не имеет смысла, а одновременная запись значений в различные объекты заблокированной группы несколькими источниками не приводит ни к каким отрицательным последствиям.

