Улучшение обменов по правилам через COM-соединение

В типовых конфигурациях есть замечательный механизм обмена по правилам через COM-соединение. Объекты по одному передаются из базы-источника в базу-приемник, подключенную через COM. В результате не требуется промежуточный файл обмена, иногда большой и процесс обмена более контролируемый. Тем не менее, типовой механизм можно улучшить и добиться, чтобы, как только объект передавался в базу-получатель, сразу же бы удалялась и регистрация изменений для базы-получателя. Несколько строк кода приносят волшебный эффект!

Назначение улучшения

Улучшение позволяет принести много положительных эффектов в обмены через COM:

  1. Основная цель. Если выгрузка(загрузка) завершается с ошибкой, то уже переданные объекты не будут передаваться повторно. Особенно это хорошо в случаях, когда обмены не проходили длительное время и накопился большой объем изменений. Большие обмены длятся долго и могут вылететь, их приходится назначать сначала.
  2. Борьба с коллизиями. Если даже выгрузка происходит успешно, но не происходит загрузки, нет подтверждения о том, что объект получен, соответственно, он будет передаваться еще раз. Это может привести к коллизиям, т.к. за время между обменами объект могли изменить. Мы можем удалить регистрацию изменений и не дожидаясь подтверждения в виде загрузки из базы-получателя, ведь и так понятно, что объект туда ушел.
  3. Страх отложенных движений. Когда документ передается повторно, он распроводится. Это пугает пользователей, они видят, что документ был сперва проведен, потом распроводится. Особенно это страшно в случае больших обменов, когда могут распроводиться большие массивы документов. По этой схеме документ передается только один раз.

 

Реализация

Сначала я беспокоился, что обмен по COM-соединению реализован через выгрузку во временный файл обмена. Но, к счастью, передача идет по одному объекту.

 

Изменения нужно вносить в обработку ОбменДаннымиXML: в процедуру ВыполнитьВыгрузкуИзмененныхДанныхДляУзлаОбмена в цикл по перебору изменений. Добавляемый код выделен жирным курсивом:

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

                                       

       Пока ВыборкаИзменений.Следующий() Цикл

 

              //Осипов - сразу удаляем регистрацию измений, отмечаем что передали...

              Если НепосредственноеЧтениеВИБПриемнике Тогда //Типовой флаг. Обозначает обмен через COM

                    ПланыОбмена.УдалитьРегистрациюИзменений(ЗаписьСообщения.Получатель, Данные);

             КонецЕсли;

 

      

             Если ИспользоватьТранзакцииПриВыгрузкеДляПлановОбмена

             И (КоличествоЭлементовВТранзакцииПриВыгрузкеДляПлановОбмена > 0)

             И (КоличествоНайденныхДляЗаписиОбъектов = КоличествоЭлементовВТранзакцииПриВыгрузкеДляПлановОбмена) Тогда

                          

                    // промежуточную транзакцию закрываем и открываем новую

                    ЗафиксироватьТранзакцию();

                     НачатьТранзакцию();

                    КоличествоНайденныхДляЗаписиОбъектов = 0;

             КонецЕсли;

                   

       КонецЦикла;

 

Важно! Изменения нужно добавить в код обработок обеих базах. Почему? Обычно обмен двухсторонний.

Обмен происходит в процедуре ПроцедурыОбменаДанными. ВыполнитьОбменДаннымиЧерезComСоединение.

Сначала происходит загрузка из базы-приемника, при этом вызывается экземпляр обработки обмена из базы-приемника  ОбработкаОбменаПриемника.ВыполнитьВыгрузку. Поэтому важно, чтобы в базе-приемнике обработка тоже была пропатчена аналогичным образом.

Затем идет выгрузка из базы-отправителя, используется уже обработка из базы-отправителя

ВыполнитьВыгрузку.     

 

Проверка

В журнале регистрации базы-получателя видим, что пришел документ РОТ 3006:

 

 

 

В мониторе обмена в базе-отправителе видим, что объект зарегистрирован:

 

Теперь выполним код по удалению, посмотрим монитор обмена, однако вместо ожидаемого удаления документа РОТ из зарегистрированных изменений увидим ошибку:

Дело в том, что в настройке обмена указан размер транзакции – 200 объектов:

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

Еще одно свидетельство, до обмена количество зарегистрированных изменений было большим:

После обмена добавились только свежие изменения (в тестовой базе активно работают пользователи):

Заключение

Эта статья замечательно показывает, как минимальное, точечное вмешательство, может привести к потрясающему эффекту. Как тут не вспомнить анекдот про сантехника, который приходит, тыкает пальцем и берет за это 1000 рублей, объясняя – сам тык стоит 1 рубль, но время, в течении которого я изучал этот тык стоит 999 рублей.

 

Сначала я обсуждал эту проблему на инфостарте в контексте:

1С:Предприятие 8.1 (8.1.15.14)
"Управление торговлей", редакция 10.3 (10.3.7.9)
В УТ настроен обмен с Розницей по правилам обмена через COM-соединение.
Хочу, чтобы при выгузке из УТ в Розницу (из базы-отправителя в базу-получатель), когда документ передан в базу-получатель и зарегистрирован в отложенных движениях, чтобы он удалялся из плана-обмена базы-отправителя (УТ).
Т.к. иногда выгрузка не доходит до конца, или же не получает подтверждения, чтобы данные повторно не гонялись
.

 

К сожалению, никто мне там не подсказал этого замечательного решения, пришлось до всего додумываться самому.