До данного момента рассматривались только механизмы регистрации и удаления регистрации изменений. Рассмотрим пример кода, реализующий (в рамках универсального обмена) полный цикл выгрузки данных (включает в себя выборку данных, для которых были зарегистрированы изменения). При этом в качестве файлов «носителей данных» будут использоваться документы XML.
Следует отметить, что обмен данными может выполняться через файлы других форматов, но записать/прочитать данные с помощью объектов ЧтениеСообщенияОбмена и ЗаписьСообщенияОбмена без указания в качестве параметра объектов читающих и записывающих XML нельзя (листинг 3.46).
Листинг 3.46. Пример выгрузки данных
ЗаписьXML = Новый ЗаписьXML()
ЗаписьXML.ОткрытьФайл(ИмяФайлаСообщения);
Узел = ПланыОбмена.УдаленныеСклады.НайтиПоКоду(КодУзла);
ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
ЗаписьСообщения.НачатьЗапись(ЗаписьXML, Узел);
Выборка = ПланыОбмена.ВыбратьИзменения(Узел, ЗаписьСообщения.НомерСообщения);
Пока Выборка.Следующий() Цикл
Данные = Выборка.Получить();
ЗаписатьXML(ЗаписьXML, Данные);
КонецЦикла;
ЗаписьСообщения.ЗакончитьЗапись();
Для получения выборки данных, для которых зарегистрированы изменения, используется метод ВыбратьИзменения(). Для обхода полученных данных используется метод Следующий() выборки. В процессе выборки изменений в записи таблиц регистрации изменений (которые раньше не выгружались и у которых, соответственно, в поле таблицы НомерСообщения находится значение Null) проставляется номер сообщения обмена данными, в котором должны передаваться изменения.
Представленный алгоритм выгрузки предполагает, что отправленные сообщения могут быть потеряны по тем или иным причинам. Если потерь сообщения не может быть в принципе (гарантированная доставка), то в конце алгоритма можно поместить следующую строку (листинг 3.47).
Листинг 3.47. Удаление регистрации изменений при гарантированной доставке
ПланыОбмена.УдалитьРегистрациюИзменений(Узел, НомерСообщения);
В этом случае из таблицы регистрации изменений будут удалены записи, относящиеся к узлу, ссылка на который передана в качестве первого параметра метода. Причем будут удалены не все записи, а только те, в которых номер сообщения равен или меньше того значения, которое передано в качестве второго параметра метода. Это те записи, в которых была произведена первая отправка изменений.
Фрагмент кода, в котором производится чтение сообщения, содержащего измененные данные, выглядит следующим образом (листинг 3.48).
Листинг 3.48. Пример чтения сообщения обмена
ЧтениеXML = Новый ЧтениеXML()
ЧтениеXML.ОткрытьФайл(ИмяФайлаСообщения);
ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();
ЧтениеСообщения.НачатьЧтение(ЧтениеXML);
ПланыОбмена.УдалитьРегистрациюИзменений(ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого);
Пока ВозможностьЧтенияXML(ЧтениеXML) Цикл
Данные = ПрочитатьXML(ЧтениеXML);
Данные.ОбменДанными.Отправитель = ЧтениеСообщения.Отправитель;
Данные.ОбменДанными.Загрузка = Истина;
Данные.Записать();
КонецЦикла;
ЧтениеСообщения.ЗакончитьЧтение();
В приведенных выше примерах чтения и записи сообщений не учитывалось, что при обмене данными может случиться так, что один и тот же элемент данных будет изменен одновременно в двух обменивающихся данными узлах. В этом случае непонятно, какое из изменений должно быть в конечном счете принято. Такая ситуация называется коллизией.
Один из способов разрешить коллизию – определить, какой из узлов является главным, а какой – подчиненным. При этом должно быть принято изменение, сделанное в главном узле, а изменение, сделанное в подчиненном узле, должно быть отвергнуто.
Для реализации этого при приеме сообщения перед записью данных необходимо установить, зарегистрировано ли изменение этих данных, и в зависимости от роли узла в данной паре «получатель – отправитель» принять решение: записывать или не записывать данные.
Ниже (листинг 3.49) приведен пример реализации стратегии «главный – подчиненный» при чтении сообщения. Предполагается, что для хранения роли узла в плане обмена был определен реквизит Главный, имеющий тип Булево.
Листинг 3.49. Пример реализации стратегии «главный – подчиненный»
ЧтениеXML = Новый ЧтениеXML()
ЧтениеXML.ОткрытьФайл(ИмяФайлаСообщения);
ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();
ЧтениеСообщения.НачатьЧтение(ЧтениеXML);
ПланыОбмена.УдалитьРегистрациюИзменений(ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого);
Отправитель = ЧтениеСообщения.Отправитель;
Главный = Отправитель.Главный;
Пока ВозможностьЧтенияXML(ЧтениеXML) Цикл
Данные = ПрочитатьXML(ЧтениеXML);
Если Главный ИЛИ (Не ПланыОбмена.ИзменениеЗарегистрировано(Отправитель, Данные)) Тогда
Данные.ОбменДанными.Отправитель = ЧтениеСообщения.Отправитель;
Данные.ОбменДанными.Загрузка = Истина;
Данные.Записать();
КонецЕсли;
КонецЦикла;
ЧтениеСообщения.ЗакончитьЧтение();
Следует обратить внимание на необходимость установки у загружаемого элемента данных свойства Загрузка в значение Истина. В обработчиках событий записи объекта рекомендуется отслеживать данный режим и не делать каких-либо проверок на корректность заполнения, присутствие каких-либо связанных данных. Это обусловлено тем фактом, что на момент загрузки данного объекта другие объекты могут быть еще не загружены.