1С-Предприятие 8.0. Практическое пособие разработчика

       

Программный обмен в распределенной информационной базе


Все описанные выше действия по обмену данными в распределенной информационной базе можно выполнить программно.

Мы создадим обработку, которая будет программно выполнять для выбранного узла все те действия, которые были рассмотрены в предыдущем разделе. [433]

Для этого в конфигураторе центральной базы создадим новый объект конфигурации Обработка с именем "ОбменСОтделениями". Создадим основную форму обработки и расположим на ней поле ввода с именем "ПолеВводаОтделение", подписью "Отделение:" и типом ПланОбменаСсылка.Отделения:

После этого расположим в форме три кнопки: "Создать начальный образ" с именем "КнопкаСоздатьНачальныйОбраз", "Записать изменения" с именем "КнопкаЗаписатьИзменения" и "Прочитать изменения" с именем "КнопкаПрочитатьИзменения":


[434]

Начнем с создания обработчика нажатия кнопки "Создать начальный образ". Текст обработчика будет выглядеть следующим образом:



Процедура КнопкаСоздатьНачальныйОбразНажатие(Элемент)

Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога);

   Диалог.Заголовок = "Укажите каталог информационной базы:";

   Если Диалог.Выбрать() Тогда

       ПланыОбмена.СоздатьНачальныйОбраз(ПолеВводаОтделение,"File=" + Диалог.Каталог);

       Предупреждение("Создание начального образа узла завершено.");

   КонецЕсли;

КонецПроцедуры

В начале процедуры мы вызываем диалог выбора каталога, в который будет помещен образ информационной базы, и затем выполняем метод СоздатьНачальныйОбраз() объекта ПланыОбменаМенеджер. Именно этот метод и позволяет нам создать образ подчиненного узла распределенной информационной базы. В первом параметре метода передается ссылка на узел, для которого мы хотим создать начальный образ, а во втором – строка соединения, указывающая информационную базу.




Теперь создадим обработчик нажатия кнопки "Записать изменения":

Процедура КнопкаЗаписатьИзмененияНажатие(Элемент)

   Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);

   Диалог.Заголовок = "Укажите файл обмена:";

   Если Диалог.Выбрать() Тогда

       // Создать и проинициализаровать объект ЗаписьХМL

       ЗаписьXML = Новый ЗаписьXML;

       ЗаписьXML.ОткрытьФайл(Диалог.ПолноеИмяФайла);

       // Создать объект ЗаписьСообщенияОбмена и начать запись сообщения

       ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();

       ЗаписьСообщения.НачатьЗапись(ЗаписьXML, ПолеВводаОтделение);

       // Записать содержимое тела сообщения обмена данными распределенной ИБ

       ПланыОбмена.ЗаписатьИзменения(ЗаписьСообщения);

       // Закончить запись сообщения и запись ХМL

       ЗаписьСообщения.ЗакончитьЗапись(); [435]

       ЗаписьXML.Закрыть();

       Предупреждение("Запись изменений завершена.");

   КонецЕсли;

КонецПроцедуры

В начале процедуры мы вызываем диалог ввода имени файла, в который будут записаны изменения. После этого мы создаем объект ЗаписьXML для работы с этим файлом. Затем создаем объект ЗаписьСообщенияОбмена, с помощью которого будем создавать сообщение обмена. В методе НачатьЗапись(), во втором параметре, мы указываем, для какого узла обмена будет создаваться это сообщение. После этого мы выполняем метод ЗаписатьИзменения() объекта ПланыОбменаМенеджер, который и записывает изменения, предназначенные для передачи в выбранный узел, в указанное сообщение обмена. В заключение мы как обычно заканчиваем запись сообщения обмена и закрываем файл.





Узнай больше!

Следует отметить, что метод ЗаписатьИзменения() позволяет задать максимальное число элементов данных, которые помещаются в сообщение в рамках одной транзакции базы данных. По умолчанию все данные помещаются в сообщение в рамках одной транзакции. Такой режим является рекомендуемым, так как гарантирует согласованность данных, помещаемых в сообщение.

Но при создании сообщения в многопользовательском режиме могут быть конфликты блокировок между транзакцией, в которой данные помещаются в сообщение, и транзакциями, выполняемыми другими пользователями. Для снижения вероятности возникновения таких конфликтов можно задать значение этого параметра, отличное от значения по умолчанию. Чем меньше значение параметра, тем меньше вероятность конфликта блокировок, но выше вероятность помещения в сообщение несогласованных данных.

Учитывая все вышесказанное, идеальным вариантом является выполнение обмена данными в монопольном режиме. Однако такой вариант не всегда приемлем, в силу специфики организации работы конкретных информационных баз. [436]

И последним мы создадим обработчик нажатия кнопки "Прочитать изменения":

Процедура КнопкаПрочитатьИзмененияНажатие(Элемент)

   Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);

   Диалог.Заголовок = "Укажите файл обмена:";

   Если Диалог.Выбрать() Тогда

       // Создать и проинициализаровать объект ЧтениеХМL

       ЧтениеXML = Новый ЧтениеXML;

       ЧтениеXML.ОткрытьФайл(Диалог.ПолноеИмяФайла);

       // Создать объект ЧтениеСообшенияОбмена и начать чтение сообщения

       ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();

       ЧтениеСообщения.НачатьЧтение(ЧтениеXML);

       // Прочитать содержимое тела сообщения



       ПланыОбмена.ПрочитатьИзменения(ЧтениеСообщения);

       // Закончить чтение сообщения и чтение XML

       ЧтениеСообщения.ЗакончитьЧтение();

       ЧтениеXML.Закрыть();

       Предупреждение("Чтение изменений завершено.");

   КонецЕсли;

КонецПроцедуры

В начале процедуры мы снова вызываем диалог ввода имени файла, который будет прочитан, и создаем объект ЧтениеXML для работы с этим файлом. Затем создаем объект ЧтениеСообщенияОбмена для чтения сообщения, содержащегося в указанном файле. Затем методом ПрочитатьИзменения() объекта ПланыОбменаМенеджер мы читаем полученное сообщение. В заключение процедуры мы завершаем чтение сообщения обмена и закрываем файл.

Проверить работу нашей обработки можно на примере, аналогичном приведенному в разделе универсального обмена Данными.[437]

Следует лишь сделать несколько заключительных замечаний.

При использовании механизма распределенных информационных баз становятся доступными четыре события объект ПланОбменаОбъект, которые позволяют управлять отправкой \ приемом данных на уровне отдельных элементов данных:

·ПриОтправкеДанныхГлавному(),
·ПриОтправкеДанныхПодчиненному(),
·ПриПолученииДанныхОтГлавного(),
·ПриПолученииДанныхОтПодчиненного().
Эти события будут вызываться для каждого элемента данных включаемого в сообщение. Работу этих событий можно увидеть добавив в модуль объекта План обмена следующий текст:

Процедура ПриОтправкеДанныхГлавному(ЭлементДанных, ОтправкаЭлемента)

   Сообщить("ПриОтправкеДанныхГлавному "+ЭлементДанных);

КонецПроцедуры

Процедура ПриОтправкеДанныхПодчиненному(ЭлементДанных, ОтправкаЭлемента)

   Сообщить("ПриОтправкеДанныхПодчиненному "+ЭлементДанных);

КонецПроцедуры

Процедура ПриПолученииДанныхОтГлавного(ЭлементДанных, ПолучениеЭлемента, ОтправкаНазад)



   Сообщить("ПриПолученииДанныхОтГлавного "+ЭлементДанных);

КонецПроцедуры

Процедура ПриПолученииДанныхОтПодчиненного(ЭлементДанных, ПолучениеЭлемента, ОтправкаНазад)

   Сообщить("ПриПолученииДанныхОтПодчиненного "+ЭлементДанных);

КонецПроцедуры

В первом параметре всех перечисленных событий находится тот элемент данных, для которого вызвано это событие. [438]

Параметр "ОтправкаЭлемента" позволяет управлять тем, какая информация будет помещена в сообщение. Он может принимать три значения:

·ОтправкаЭлементаДанных.Авто – значение по умолчанию – указывает на то, что элемент данных будет помещен в сообщение,
·ОтправкаЭлементаДанных.Удалить – в сообщение будет помещено значение, предназначенное для удаления этого элемента данных,
·ОтправкаЭлементаДанных.Игнорировать – в сообщение не будет помещено ничего, связанного с этим элементом данных.
Параметр "ПолучениеЭемента" позволяет указать, будет ли прочитанный элемент данных записан в базу данных, или нет. Параметр также может принимать три значения:

·ПолучениеЭлементаДанных.Авто – значение по умолчанию. Если элемент данных получен от главного узла – он будет записан всегда. Если элемент данных получен от подчиненного узла, он будет записан только в случае, если не зарегистрированы изменения для этого элемента данных,
·ПолучениеЭлементаДанных.Принять – полученный элемент данных будет записан всегда,
·ПолучениеЭлементаДанных.Игнорировать – проигнорировать получение элемента данных и ничего не записывать.
Также в событиях получения данных существует третий параметр – "ОтправкаНазад", имеющий тип Булево. Этот параметр позволяет выполнять принудительную регистрацию изменений для полученного элемента данных в базе-получателе. Такая необходимость может возникнуть, например, в случае, когда при приеме данных от узла-отправителя обнаружено, что полученные данные противоречивы (например, в узле-отправителе была допущена ошибка при изменении Данных). Тогда мы можем проигнорировать присланные изменения и, подняв флаг "ОтправкаНазад", вызвать принудительную регистрацию изменений полученного элемента данных в нашей базе для узла-отправителя. В результате последующего обмена состояние этого [439] элемента данных в узле-отправителе будет установлено таким же, как и в нашей базе.



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

Для этого следует использовать метод УстановитьГлавныйУзел() объекта ПланыОбменаМенеджер. В параметре этого метода передается ссылка на узел плана обмена распределенной информационной базы, который устанавливается главным для текущей базы. Также в этом параметре может быть передано значение Неопределено, и это приведет к тому, что у текущей информационной базы будет отсутствовать главный узел.

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

Допустим, необходимо переместить один из подчиненных узлов в корень дерева:



Для этого следует выполнить следующие действия:

// В информационной базе Узла2

ПланыОбменаМенеджер.УстановитьГлавныйУзел(Неопределено); [440]

// В информационной базе Узла1

ПланыОбменаМенеджер.УстановитьГлавныйУзел(Узел2);

При этом будут удалены все записи регистрации изменений конфигурации Узла1, относящиеся к Узлу2, т.к. передача изменений конфигурации будет возможна теперь только от Узла2 к Узлу1. Записи регистрации изменения данных удалены не будут, т.к. передача изменений данных будет по-прежнему возможна между этими узлами.

Таким же образом, используя значение параметра метода Неопределено, мы можем отключать от дерева отдельную информационную базу или целое поддерево:



// В информационной базе Узла1

ПланыОбменаМенеджер.УстановитьГлавныйУзел(Неопределено); [441]

Кроме этого мы можем создавать распределенную информационную базу из отдельных информационных баз с идентичной конфигурацией:



// В информационных базах Узла2, Узла3 и Узла4

ПланыОбменаМенеджер.УстановитьГлавныйУзел(Узел1); [442]

Содержание раздела