Любой механизм регистрации изменений должен решать следующие вопросы:
1. Гранулярность.
Не всегда нужно знать об изменении каждой записи. Иногда достаточно просто знать, что изменилась какая-то одна из записей таблицы. При проектировании системы обмена данными необходимо чётко понимать какого масштаба изменения нас интересуют. Это называется гранулярностью отслеживания изменений и она может быть разной, в том числе для разных объектов своя. Это скорее логическое понятие, чем физическое. Например гранулярность может быть следующих уровней:
- информационная база (база данных);
- объект конфигурации (таблица базы данных);
- объект конфигурации (запись таблицы базы данных);
- реквизит объекта конфигурации (поле записи таблицы базы данных);
- узел обмена (набор записей таблицы базы данных, отобранных по какому-то признаку).
Как правило используется отслеживание изменений на уровне записей таблиц (объектов). Мы настолько привыкли к этому, что какие-то другие варианты чаще всего даже не рассматриваются. Гранулярность уровня реквизитов используется для разработки систем аудита изменения данных. Однако аудит изменений и обмен данными это разные механизмы, которые решают разные задачи. Если говорить об обменах, то уровень реквизитов можно использовать для оптимизации обменов с точки зрения уменьшения объёмов передаваемых данных. Иногда это имеет смысл.
2. Способ репликации.
Различают два вида обмена данными (репликации):
- репликация транзакций;
- репликация моментального снимка (snapshot).
В первом случае в обмене участвуют команды изменения данных. Такие как добавление, изменение и удаление объектов конфигурации. Все команды записываются в хронолигическом порядке в какую-нибудь очередь, например, реализованную в виде регистра сведений. Затем они ровно в такой же последовательности передаются в узел-приёмник и там выполняются всё также последовательно. Это в какой-то степени похоже на систему аудита изменений или версионирования объектов, но специально оптимизированную для обменов данными. У такого подхода есть свои плюсы, например, полное отсутствие блокировок при одновременной регистрации изменений и выгрузке данных. Даже удаление уже обработанных изменений можно выполнять параллельно этим двум процессам. К недостаткам можно отнести увеличение размеров таблиц регистрации изменений и количества передаваемых по сети сообщений. Кроме этого, в случае сбоя системы можно последовательно воспроизвести загрузку сообщений начиная от момента сбоя до текущей рабочей даты.
Во втором случае в обмене участвуют только текущие актуальные данные, которые являются результатом выполненных ранее изменений. Этакий снимок данных на момент выполнения очередного сеанса обмена. Кстати сказать, планы обмена относятся именно к этому виду репликации. Преимущество здесь очевидно - меньше данных передаётся между узлами обмена. Однако сложность реализации такого вида обмена данными очень высока. Исторических данных нет и об этом нужно помнить. В случае системного сбоя или потери связи между узлами на достаточно продолжительное время, необходимо чательно продумывать методику приведения распределённой информационной системы в синхронизированное состояние. Как правило эта проблема решается выгрузкой всех или большей части данных из узла-источника в узел-приёмник повторно. Такая операция называется повторная инициализация или реинициализация приёмника данных.
3. Содержание одного сообщения.
Сообщение обмена может содержать один объект. Объект и его движения или какие-то другие зависимые данные. Это может быть одна транзакция, состоящая из нескольких команд. Граф объектов с заданой глубиной относительно корневого объекта. Что включать в сообщение обмена это не простой вопрос. Он напрямую связан с реализацией требований по поддержанию системы в актуальном и целостном состоянии. Чем жёстче эти требования, тем выше цена ошибки. Кроме этого решение этого вопроса влияет на производительность системы обмена данными, её пропускную способность, параллельность работы пользователей и другие аспекты функционирования обменов. Например, чем меньше сообщения, тем короче транзакции по их загрузке, тем выше параллельность работы пользователей. Часто бывает так, что битые ссылки недопустимы для логики прикладного решения - требуется согласованная выгрузка зависимых объектов.
4. Требование целостности регистрации изменения.
Тут всё просто: регистрация изменения фиксирует факт изменения данных. Нельзя допускать "потерянных" или "фантомных" изменений. Это когда, в первом случае, есть изменение данных, но его регистрация не выполнилась, а во втором - изменение данных откатилось, а его регистрация всё-таки выполнилась. Как первый, так и второй случай вполне возможны, когда регистрация изменений выполняется не в транзакции. Такое может быть, например, при использовании в качестве системы хранения и передачи изменений какого-нибудь менеджера очередей, например, ActiveMQ или RabbitMQ, которые сейчас становятся модными. Проблема заключается в том, что платформа 1С:Предприятие 8 не предоставляет средств для объединения в одну транзакцию записи данных объектов 1С и внешних ресурсов. Впрочем, если это не существенно с точки зрения прикладного решения, то этим можно принебречь, но забывать не стоит.
5. Требования параллельности.
Идеальная система регистрации изменений должна в любой момент времени позоволять параллельно выполнять три задачи: регистрация новых изменений, выгрузка изменёных данных, удаление уже обработанных регистраций. В высоко нагруженных системах это требование должно выполняться 100%. Ну, или хотя бы стремиться к этому ...
6. Фильтрация и маршрутизация.
Очень часто логику маршрутизации и фильтрации сообщений интегрируют с подсистемой регистрации изменений. Это может быть очень вредно, так как чем сложнее логика такой маршрутизации, тем большее влияние она оказывает на длительность транзакции основного бизнес-объекта, который изменяется. Более того, иногда можно увидеть решения, где маршрутизация тесно переплетается с бизнес-логикой и становится трудно понять что важнее: бизнес или обмен данными. Здесь не следует увлекаться. Нужно искать какой-то разумный баланс. По возможности отделить логику маршрутизации от функции регистрации изменений.
7. Изменение структур данных.
При проектировании подсистемы регистрации изменений следует заранее подумать как она будет работать в случае изменения структур данных, изменение которых она отслеживает. Чаще всего, когда реализуется нетиповая подсистема регистрации изменений, приходится дополнительно как-то отслеживать изменение структур данных. Бывает, что для решения задачи вполне достаточно соблюдать некоторый регламент обновления конфигурации 1С, чтобы не было проблем с обменами данных.
9. Удаление обработанных регистраций.
Обработанные регистрации изменений нужно как-то удалять. Желательно, чтобы это не мешало работе пользователей и выгрузке изменений.
Заключение.
Обмен данными не бывает простым, а выбор подсистемы регистрации изменений является ключом к его успешной реализации.
В качестве предложения реализации альтернативной планам обмена подсистемы регистрации изменений реализовал проект DaJet Exchange для 1С:Предприятие 8.
Кратко суть:
1. Интегрируемая конфигурация 1С объединяется с конфигурацией DaJetExchange.cf.
2. Создаётся файл настроек dajet-exchange-settings.json, который управляет регистрацией изменений в интегрируемой конфигурации.
3. Все изменения попадают в справочник - очередь исходящих сообщений DaJetExchangeQueue.
4. Регистрация изменений работает очень быстро и без блокировок СУБД.
5. Сообщения сериализуются в JSON.
6. Внешняя система забирает сообщения из очереди исходящих сообщений.
7. Внешняя система берёт на себя всю логику обработки и маршрутизации сообщений по узлам РИБ, если они есть, или в адрес других информационных систем.