Передача большого количества объектов через Web-сервисы

Публикация № 582886

Разработка - Системная интеграция - Интеграция с WEB

Web-сервис веб - сервис

Один из вариантов передачи большого количества объектов при использовании Web-сервисов.

Дисклеймер

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

Вместо введения 

Собственно, что мы имеем - имеем две конфигурации, одна написанная с нуля для работы кассиров в магазинах, так называемый FrontOffice, вторая Управление торговлей, редакция 11.2 (11.2.3.108). В обе конфигурации встроена БСП версии 2.3.2.50.  Между конфигурациями существует обмен данными через Web-сервисы. Сам обмен и транспорт обмена полностью типовой, добавлен только свой план обмена. Обмен между базами происходит раз в 5 минут и в среднем очень маленький, в пределах 100 - 150 объектов за одну итерацию. Ввиду того что обмен работает через Web-сервис а магазины (FrontOffice) географически находятся в разных местах мы имеем несколько ограничений. Первое ограничение связано с тем что с разными магазинами (FrontOffice) разные каналы связи, которые соответственно имеют разную пропускную способность (от 2 Мбит до 50 Мбит), что в свою очередь накладывает серьезные ограничения на передаваемый объем данных. Второе ограничения связано с передачей данных на стороне веб сервера. Как пишут в статьях и на форумах максимальный размер пакета, который стабильно может передаваться через веба сервер варьируется от 16 Мб до 30 Мб (при настройках по умолчанию в зависимости от Web-сервера).  По факту, ради эксперимента, я передавал файл через Web-сервис размером примерно 130 Мб в локальной сети, и он проходил, без каких-либо доработок, но не понятно, как это сказывалось на работоспособности веб сервера (так как не рекомендуется передавать данные больше нескольких Мб) и как бы это все происходило при пропускной способности канала 2 Мбита.

О проблеме 

Суть проблемы заключается в том, что в определённый момент времени нужно передать порядка> 60000 объектов + примерно 40000 объектов должны были выгрузиться по ссылкам. При попытке выгрузить такое количество данных на магазин с пропускной способностью канала в 50 Мбит происходило следующее. План обмена на стороне инициатора обмена показывал, что все данные успешно выгружены, не сжатый файл выгрузки при этом "весил" примерно 800 Мб в сжатом виде примерно 13 Мб. А на принимающей стороне отображалось информация о том, что ничего не происходит и весь журнал регистрации заполнялся ошибками, т.к. обмен пытался каждые 5 минут запуститься заново, но не запускался из-за ошибки, что уже идет обмен данными. Так могло продолжаться пол дня и сутки и ничего в итоге не загружалось, обмен просто подвисал. По идее, при передачи данных через web-сервис (если верить исходному коду и описанию) происходит разбивка выгружаемых данные на файлы примерно по 1 Мб их передача, а затем склеивание и загрузка. Происходит это в общем модуле ОбменДаннымиСервер:

// Функция передает указанный файл в сервис передачи файлов.
//
// Параметры:
//  ИмяФайла                 - Строка - путь к передаваемому файлу.
//  ПараметрыДоступаКСервису - Структура: АдресСервиса, ИмяПользователя, ПарольПользователя. 
//  РазмерЧасти              - Число - размер части в килобайтах. Если значение равно 0,
//                             то разбивка на части не производится.
// Возвращаемое значение:
//  УникальныйИдентификатор  - идентификатор файла в сервисе передачи файлов.
//
Функция ПоместитьФайлВХранилищеВСервисе(Знач ИмяФайла, Знач УзелИнформационнойБазы, Знач РазмерЧасти = 1024, Знач ПараметрыАутентификации = Неопределено)
	
	// Возвращаемое значение функции.
	ИдентификаторФайла = Неопределено;
	
	Прокси = ПолучитьWSПроксиДляУзлаИнформационнойБазы(УзелИнформационнойБазы,, ПараметрыАутентификации);
	
	ОбменВыполняетсяВОднойСети = ОбменДаннымиПовтИсп.ОбменВыполняетсяВОднойЛокальнойСети(УзелИнформационнойБазы, ПараметрыАутентификации);
	
	Если ОбменВыполняетсяВОднойСети Тогда
		
		ИмяФайлаВХранилище = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(КаталогВременногоХранилищаФайлов(), УникальноеИмяФайлаСообщенияОбмена());
		
		ПереместитьФайл(ИмяФайла, ИмяФайлаВХранилище);
		
		Прокси.PutFileIntoStorage(ИмяФайлаВХранилище, ИдентификаторФайла);
		
	Иначе
		
		КаталогФайлов = ПолучитьИмяВременногоФайла();
		СоздатьКаталог(КаталогФайлов);
		
		// Архивирование файла
		ИмяНеразделенногоФайла = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(КаталогФайлов, "data.zip");
		Архиватор = Новый ЗаписьZipФайла(ИмяНеразделенногоФайла,,,, УровеньСжатияZIP.Максимальный);
		Архиватор.Добавить(ИмяФайла);
		Архиватор.Записать();
		
		// Разделение файла на части
		ИдентификаторСессии = Новый УникальныйИдентификатор;
		
		КоличествоЧастей = 1;
		Если ЗначениеЗаполнено(РазмерЧасти) Тогда
			ИменаФайлов = РазделитьФайл(ИмяНеразделенногоФайла, РазмерЧасти * 1024);
			КоличествоЧастей = ИменаФайлов.Количество();
			Для НомерЧасти = 1 По КоличествоЧастей Цикл
				ИмяФайлаЧасти = ИменаФайлов[НомерЧасти - 1];
				ДанныеФайла = Новый ДвоичныеДанные(ИмяФайлаЧасти);
				Прокси.PutFilePart(ИдентификаторСессии, НомерЧасти, ДанныеФайла);
			КонецЦикла;
		Иначе
			ДанныеФайла = Новый ДвоичныеДанные(ИмяНеразделенногоФайла);
			Прокси.PutFilePart(ИдентификаторСессии, 1, ДанныеФайла);
		КонецЕсли;
		
		Попытка
			УдалитьФайлы(КаталогФайлов);
		Исключение
			ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииУдалениеВременногоФайла(),
				УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		КонецПопытки;
		
		Прокси.SaveFileFromParts(ИдентификаторСессии, КоличествоЧастей, ИдентификаторФайла);
		
	КонецЕсли;
	
	Возврат ИдентификаторФайла;
КонецФункции

Да и действительно файл разбивается на части, в случае если он больше 1 Мб и передается, но в нашем случае данные метод не помогает, обмен все равно зависает, где то при попытке все эти данные передать и загрузить. Тогда в общем то и родилась идея передавать данные частями, а точнее выгружать определённое количество объектов за одну итерацию обмена данными. К примеру, если зарегистрировано 10000 изменений по справочникам мы их выгружаем по 1000 за одну итерацию обмена, пока не выгрузим все 10000 объектов. Тем самым мы уменьшаем нагрузку на канал, уменьшаем время выгрузки и загрузки за одну итерацию и в общем если канал связи совсем слабый, то гарантированно передаем необходимое количество данных за раз. Идея реализации была в том, чтобы выгрузка продолжала работать через типовые средства при помощи БСП, но в случае необходимости, делала это частями.

Реализация

Собственно, сам алгоритм получился примерно следующий:

Блок схема

1.      Сначала проверяем количество зарегистрированных объектов (наборов записей) на целевом плане обмена и соответственно узле. Если количество объектов меньше чем установлено в ограничении, то никаких дополнительных ограничений не накладываем, просто выгружаем все как есть типовыми механизмами.

2.      Если количество зарегистрированных изменений по справочникам больше чем установлено в ограничении, то сначала порционно выгружаются данные из справочников. Справочники выгружаются в первую очередь, чтобы между выгрузкой справочников и регистров в регистрах не было «Объект не найден»

3.      Если количество зарегистрированных объектов больше чем установлено в ограничении и есть зарегистрированные изменения по регистрам, то порционно выгружаются регистры (сведений и накоплений).

Может возникнуть вопрос, почему не выгружать одновременно справочники и регистры, если количество зарегистрированных изменений не превышает ограничение. Ответ кроется в функции ВыбратьИзменения у менеджера плана обмена. Что она собственно делает? Описание из синтаксис помощника 1С:Предприятие:

Синтаксис:

ВыбратьИзменения(<Узел>, <НомерСообщения>, <ФильтрВыборки>)

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

В чем ее смысл – она выбирает измененные данные (зарегистрированные изменения) и проставляет в записи регистрации изменений номер сообщения обмена данными. Нам же нужно ограничить выборку определенным количеством объектов. В описании к данной функции есть важное замечание к 3 параметру «ФильтрВыборки»:

Неопределено - фильтр пуст, выбираются все изменения по узлу;
ОбъектМетаданных - выбираются изменения в основной таблице, связанной с данным объектом метаданных;
СсылкаНаОбъект - фактически, может быть выбрана только одна запись об изменении данного объекта, либо ни одной, если объект не менялся;
НаборЗаписей - набор записей регистра, может быть не выбран, для фильтрации изменений используется лишь отбор набора записей;
Массив - все элементы массива имеют один из перечисленных выше типов, кроме Неопределено. Условия фильтрации соединяются по ИЛИ.
Значение по умолчанию: Неопределено.

В замечании сказано, что если мы передаем массив каких-либо элементов для фильтрации, то все элементы должны быть одного типа, например, СправочникСсылка, или НаборЗаписей и т.д. Именно из-за этого ограничения пришлось разграничить выгрузку на справочники и регистры.

Все изменения добавляются в обработку «КонвертацияОбъектовИнформационныхБаз» в модуль объекта в процедуру «ВыполнитьВыгрузкуЗарегистрированныхДанных» после строки:

«НачальнаяВыгрузкаДанных = ОбменДаннымиСервер.УстановленПризнакНачальнойВыгрузкиДанных(ЗаписьСообщения.Получатель);»

До строки кода, которую тоже необходимо заменить:

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

В планы обмена необходимо добавить реквизит "КоличествоОбъектовВыгрузки" с типом число и добавить его на форму, в тем планы обмена, где ограничение актуально.

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

Собственно, сам код с комментариями.

	//Проверка на ограничение выгрузки данных за одну итерацию обмена данных
	//=======================================================================
	//получаем значение установленного ограничения
	КоличествоОбъектовКВыгрузке = ЗаписьСообщения.Получатель.КоличествоОбъектовВыгрузки;	
	//если ограничение установлено, то начинаем собирать запрос по объектам участвующим в обмене
	Если КоличествоОбъектовКВыгрузке <> 0 Тогда
		МассивДанныхДляОтбора = Новый Массив;
		ТекущийПланОбмена = Метаданные.ПланыОбмена[ЗаписьСообщения.Получатель.Метаданные().Имя];
		
		ТекстЗапросаОбщий = "";
		
		Для каждого СтрокаМетаданных Из ТаблицаПравилВыгрузкиИспользуемые Цикл
			СтрокаДляЗапроса = "";
			//для справочников формируем запрос с учетом того что там всегда есть Ссылка
			Если ЗначениеЗаполнено(СтрокаМетаданных.ИмяОбъектаДляЗапроса) И ТипЗнч(ТекущийПланОбмена.Состав.Найти(СтрокаМетаданных.ОбъектВыборкиМетаданные)) = Тип("ЭлементСоставаПланаОбмена") Тогда
				СтрокаДляЗапроса = СтрокаМетаданных.ИмяОбъектаДляЗапроса;
				
				//если это первый проход то указываем что это создание пакета
				Если ТекстЗапросаОбщий = "" Тогда
					ТекстЗапросаОбщий = ТекстЗапросаОбщий + "Выбрать ВД.Ссылка" + Символы.ПС + "ПОМЕСТИТЬ ВсеДанные" + Символы.ПС + " из " + СтрокаДляЗапроса + ".Изменения" + " КАК ВД ГДЕ ВД.Узел = &Узел" + Символы.ПС;
				Иначе
					ТекстЗапросаОбщий = ТекстЗапросаОбщий + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС + "Выбрать ВД.Ссылка из " + СтрокаДляЗапроса + ".Изменения" + " КАК ВД ГДЕ ВД.Узел = &Узел"  + Символы.ПС;
				КонецЕсли;
				
				//для регистров формируем запрос с учетом того что там разный набор измерений, но нам достаточно бырать Узел, чтобы подсчитать Количество объектов
				Если ЗначениеЗаполнено(СтрокаМетаданных.ИмяОбъектаДляЗапросаРегистра) И ТипЗнч(ТекущийПланОбмена.Состав.Найти(СтрокаМетаданных.ОбъектВыборкиМетаданные)) = Тип("ЭлементСоставаПланаОбмена") Тогда
					СтрокаДляЗапроса = СтрокаМетаданных.ИмяОбъектаДляЗапросаРегистра;
					//если это первый проход то указываем что это создание пакета
					Если ТекстЗапросаОбщий = "" Тогда
						ТекстЗапросаОбщий = ТекстЗапросаОбщий + "ВЫБРАТЬ ПЕРВЫЕ " + Формат(КоличествоОбъектовКВыгрузке, "ЧГ=0") + " Узел ПОМЕСТИТЬ ВсеДанные ИЗ " + СтрокаДляЗапроса + ".Изменения ГДЕ Узел = &Узел";					
					Иначе	
						ТекстЗапросаОбщий = ТекстЗапросаОбщий + "ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ПЕРВЫЕ " + Формат(КоличествоОбъектовКВыгрузке, "ЧГ=0") + " Узел ИЗ " + СтрокаДляЗапроса + ".Изменения ГДЕ Узел = &Узел";
					КонецЕсли;	
				КонецЕсли;			
			КонецЕсли;
		КонецЦикла; 
		
		//добавляем выборку данных
		ТекстЗапросаОбщий = ТекстЗапросаОбщий + Символы.ПС + "; ВЫБРАТЬ ПЕРВЫЕ " + Формат(КоличествоОбъектовКВыгрузке, "ЧГ=0") + 
		" ВсеДанные.Ссылка КАК ИзмененныйОбъект ИЗ ВсеДанные КАК ВсеДанные";
		
		ЗапросПоИзмененнымОбъектам = Новый Запрос(ТекстЗапросаОбщий);
		ЗапросПоИзмененнымОбъектам.УстановитьПараметр("Узел", ЗаписьСообщения.Получатель);
		ВыборкаПоИзмененнымОбъектам = ЗапросПоИзмененнымОбъектам.Выполнить().Выбрать();
		
		//получаем количество измененных объектов, которое в любом случае не будет больше ограничения, тем самым ускоряя выборку и проверку
		КоличествоЗарегистрированныхИзменений = ВыборкаПоИзмененнымОбъектам.Количество();
		
		//если количество зарегистрированных объектов = количеству объектов ограничения то нуобходимо ограничить выгрузку
		//проверка на "=" потому что все выборки ограничиваются количеством указанным в ограничении
		//или есди по справочникам не зарегистрировано изменений, то выгружаем РС если по ним есть что выгрузить
		Если КоличествоЗарегистрированныхИзменений = КоличествоОбъектовКВыгрузке ИЛИ КоличествоЗарегистрированныхИзменений = 0 Тогда
			//собираем запрос по изменениям из справочников
			ТекстЗапросаПоСправочникам = "";
			
			Для каждого СтрокаМетаданных Из ТаблицаПравилВыгрузкиИспользуемые Цикл
				СтрокаДляЗапроса = "";
				Если ЗначениеЗаполнено(СтрокаМетаданных.ИмяОбъектаДляЗапроса) И ТипЗнч(ТекущийПланОбмена.Состав.Найти(СтрокаМетаданных.ОбъектВыборкиМетаданные)) = Тип("ЭлементСоставаПланаОбмена") Тогда
					СтрокаДляЗапроса = СтрокаМетаданных.ИмяОбъектаДляЗапроса;
					
					Если ТекстЗапросаПоСправочникам = "" Тогда
						ТекстЗапросаПоСправочникам = ТекстЗапросаПоСправочникам + "Выбрать ПЕРВЫЕ " + Формат(КоличествоОбъектовКВыгрузке, "ЧГ=0") + " ВД.Ссылка" + Символы.ПС + "ПОМЕСТИТЬ ВсеДанные" + Символы.ПС + " из " + СтрокаДляЗапроса + ".Изменения" + " КАК ВД ГДЕ ВД.Узел = &Узел" + Символы.ПС;
					Иначе
						ТекстЗапросаПоСправочникам = ТекстЗапросаПоСправочникам + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС + "Выбрать ПЕРВЫЕ " + Формат(КоличествоОбъектовКВыгрузке, "ЧГ=0") + " ВД.Ссылка из " + СтрокаДляЗапроса + ".Изменения" + " КАК ВД ГДЕ ВД.Узел = &Узел"  + Символы.ПС;
					КонецЕсли;			
				КонецЕсли;
			КонецЦикла; 	
			//добавляем выборку данных
			ТекстЗапросаПоСправочникам = ТекстЗапросаПоСправочникам + "; ВЫБРАТЬ ПЕРВЫЕ " + Формат(КоличествоОбъектовКВыгрузке, "ЧГ=0") + " ВД.Ссылка ИЗ ВсеДанные КАК ВД"; 
			ЗапросПоИзмененнымДанным = Новый Запрос(ТекстЗапросаПоСправочникам);
			ЗапросПоИзмененнымДанным.УстановитьПараметр("Узел", ЗаписьСообщения.Получатель);
			
			//получаем данные с учетом ограничения которые будем выгружать
			МассивДанныхДляОтбора = ЗапросПоИзмененнымДанным.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");
			
			//запоминаем сколько объектов всего выгрузили
			ВсегоВыгружено = МассивДанныхДляОтбора.Количество();
			
			ТекстЗапросаПоРегистрам = "";
			
			//если не было выгрузки справочников то в этой итерации можно выгрузить регистры
			Если ВсегоВыгружено = 0 Тогда		
				Для каждого СтрокаМетаданных Из ТаблицаПравилВыгрузкиИспользуемые Цикл
				//собираем запрос по изменениям из регистров
					СтрокаДляЗапроса = "";		
					
					Если КоличествоОбъектовКВыгрузке - ВсегоВыгружено = 0 Тогда
						Прервать;
					КонецЕсли;	 
					
					Если ЗначениеЗаполнено(СтрокаМетаданных.ИмяОбъектаДляЗапросаРегистра) И ТипЗнч(ТекущийПланОбмена.Состав.Найти(СтрокаМетаданных.ОбъектВыборкиМетаданные)) = Тип("ЭлементСоставаПланаОбмена") Тогда
						СтрокаДляЗапроса = СтрокаМетаданных.ИмяОбъектаДляЗапросаРегистра;
						                                                    
						ТекстЗапросаПоРегистрам = "ВЫБРАТЬ ПЕРВЫЕ " + Формат((КоличествоОбъектовКВыгрузке - ВсегоВыгружено), "ЧГ=0") + " * ИЗ " + СтрокаДляЗапроса + ".Изменения ГДЕ Узел = &Узел";
						
						Запрос = Новый Запрос(ТекстЗапросаПоРегистрам);
						Запрос.УстановитьПараметр("Узел", ЗаписьСообщения.Получатель);
						ИзмененныеДанные = Запрос.Выполнить().Выбрать();
						
						Если ИзмененныеДанные.Количество() > 0 Тогда
							Пока ИзмененныеДанные.Следующий() Цикл
								Если ВсегоВыгружено = КоличествоОбъектовКВыгрузке Тогда
									Прервать;
								КонецЕсли;
								
								//формируем пустые наборы записей, т.к. из них нужны отборы для корректной фильтрации данных
								Если Найти(СтрокаДляЗапроса, "РегистрСведений") <> 0 Тогда					
									Набор = РегистрыСведений[СтрЗаменить(СтрокаДляЗапроса, "РегистрСведений.", "")].СоздатьНаборЗаписей();
								ИначеЕсли Найти(СтрокаДляЗапроса, "РегистрНакопления") <> 0 Тогда	
									Набор = РегистрыНакопления[СтрЗаменить(СтрокаДляЗапроса, "РегистрНакопления.", "")].СоздатьНаборЗаписей();
								КонецЕсли;				
								
								//заполняем отборы данных в зависимости от измерения конкретного регистра
								Для каждого СтрокаОтбора Из Набор.Отбор Цикл
									//Добавляем попытку, т.к. в выборке из запроса могут быть не все поля, которое есть в отборе набора
									Попытка
										СтрокаОтбора.Установить(ИзмененныеДанные[СтрокаОтбора.ПутьКДанным]);
									Исключение
									КонецПопытки;
								КонецЦикла; 
								
								МассивДанныхДляОтбора.Добавить(Набор);
								
								Инкремент(ВсегоВыгружено);
							КонецЦикла; 
						КонецЕсли;	
						
					КонецЕсли;
					
				КонецЦикла; 	
				
			КонецЕсли;
	//=======================================================================			
	// ВЫБОРКА ИЗМЕНЕНИЙ 
			ВыборкаИзменений = ОбменДаннымиСервер.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения, МассивДанныхДляОтбора);
		Иначе   
			// если количество объектов справочников к выгрузке меньше ограничения, то выгружаем только справочники, т.к. по регистрам
			// может быть Количество объктов к выгрузке большем чем ограничение
			МассивМетаданныхСправочников = ТаблицаПравилВыгрузкиИспользуемые.НайтиСтроки(Новый Структура("ИмяОбъектаДляЗапросаРегистра", Неопределено));
			МассивВыгружаемыхМетаданных = Новый Массив;
			Для каждого СтрокаМассиваМетаданныхСправочников Из МассивМетаданныхСправочников Цикл
				МассивВыгружаемыхМетаданных.Добавить(СтрокаМассиваМетаданныхСправочников.ОбъектВыборкиМетаданные);	
			КонецЦикла; 
			
			ВыборкаИзменений = ОбменДаннымиСервер.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения, МассивВыгружаемыхМетаданных);	
		КонецЕсли;
	Иначе   	
		ВыборкаИзменений = ОбменДаннымиСервер.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения, МассивВыгружаемыхМетаданных);		
	КонецЕсли;

Про быстродействие

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

Ограничения

  1. Данный код проверялся только на Управление торговлей, редакция 11.2 (11.2.3.108) и БСП 2.3.2.50 и только в режиме передачи данных через Web - сервисы, по правилам, написанным в конвертации данных 2.1. Возможно в других конфигурация потребуется какая-то доработка кода, так же и в случае использования универсально формата обмена данными.
  2. Данный код рассчитан на то, что в составе плана обмена участвуют только справочники, регистры сведений и регистры накопления. Если в плане обмена участвуют другие объекты, то код потребует доработки.

Вместо заключения

Мы были готовы потерять немного во времени выполнения обмена данными, т.к. понимали, что он стал выполняться дольше, но в итоге после данной модификации мы получили стабильно работающий обмен данными, не зависимо от количества передаваемых объектов (и соответственно объема данных). Проблемы была решена, что собственно и требовалось.

Надеюсь данное решение поможет кому то сэкономить время в случае подобной проблемы.

Скачать файлы

Наименование Файл Версия Размер
КонвертацияОбъектовИнформационныхБаз

.epf 116,77Kb
31.01.17
7
.epf 116,77Kb 7 Скачать

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. warrior1985 67 01.02.17 09:36 Сейчас в теме
3. SinglCOOLer 213 01.02.17 11:26 Сейчас в теме
2. DenisCh 01.02.17 09:43 Сейчас в теме
Я-то думал, будет что-то оригинальное...
А разбиение по кускам - это очевидное же решение...
4. SinglCOOLer 213 01.02.17 11:26 Сейчас в теме
(2) поэтому дисклеймер и написал
5. comol 4347 13.03.17 12:43 Сейчас в теме
Автор знает толк в извращениях.

Можно конечно и 60 тыс передать через web сервисы.. но зачем?

9. SinglCOOLer 213 14.03.17 11:01 Сейчас в теме
(5) Затем что есть FrontOffice на котором работают скидки и бонусы как в УТ 11, для их расчета нужно достаточно много информации
6. ipoloskov 121 13.03.17 13:08 Сейчас в теме
При решении аналогичной задачи, встал вопрос блокировки данных изменений. Как известно, план обмена блокирует таблицы изменений, начиная с операторов
ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
ЗаписьСообщения.НачатьЗапись(ЗаписьXML, УзелОбмена); 

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

после последней строчки, соответственно, план обмена начинает писать изменения с Номером+1
Оставлять все в базе заблокированным между вызовами нельзя. Как вы решили эту проблему?
7. comol 4347 13.03.17 14:25 Сейчас в теме
(6) Эх, если бы этот вопрос был решен или хоть как то решался жизнь была бы настолько проще...

Вообщем если хотим передать кучу данных - пишем их тупо в файл на ftp - самый правильный и надежный способ.
Если хотим выбрать кучу изменений - исключаем их из общего РИБ-а и выделяем в отдельный узел... ну или свой механизм регистрации пишем
Если надо чтобы "оно само" - убираем обмены и в отельную СУБД (couchDB)
8. ipoloskov 121 13.03.17 15:31 Сейчас в теме
(7) я решил так:
мне надо было передавать документы и их печатные формы. В пакете выгрузки между НачатьЗапись и ЗакончитьЗапись я выгружал только документы, без печатных форм. Документы, хотя их и много, но объем данных в выгрузке образуют небольшой. Весь образованный объем данных без труда прокачивался за один вызов.
Следующими вызовами, по частям, я запрашивал печатные формы для заданного массива документов. Там уже план обмена не используется, и ничего не блокируется.

В экстремальных случаях, если даже данные документов слишком объемны для единоразовой прокачки, можно на первом этапе выгружать и передавать только их УИДы. А все данные получать потом, частями.
11. SinglCOOLer 213 14.03.17 11:05 Сейчас в теме
(7) По моему вы как раз знаете толк в извращениях, ftp и в общем работа с файлами напрямую это лишняя и не нужная точка отказа, про РИБ вообще молчу, что то простите еще отдельную СУБД городить? Я останусь при своем мнении
12. comol 4347 14.03.17 14:53 Сейчас в теме
(11) А ограничения http протокола это не точка отказа? 6))))))))))). Будем проверять что надежнее ftp или web сервисы? :)))
13. SinglCOOLer 213 14.03.17 18:13 Сейчас в теме
(12) У нас уже все проверено, веб сервисы на бсп сами дробят файл + мы сами ограничиваем размер. Зачем нам на слабых компьютерах где работает касса грузить к примеру файл 4 гб или более? что будет с производительностью кассы в этот момент? или кассы надо будет делать на core i7 все с ssd. Как думаете что легче грузить? 4 и более гб за раз или порциями по 20 мб? Дак чем нам мешает ограничение?
14. TODD22 19 15.03.17 07:35 Сейчас в теме
(7)
Вообщем если хотим передать кучу данных - пишем их тупо в файл на ftp - самый правильный и надежный способ.

Как показывает практика не самый надёжный способ. У меня две сети магазинов. В одной ftp проработал 2 года. Неделю назад его перезагрузили. Теперь работает очень плохо.... файлы принимает через раз. Имена файлов кривые. Обмены проходят с 4-5 попытки.
Во второй сети такие же проблемы, то имена файлов кривые, то файл обмена с 3-4 попытки на ftp закидывает.


Но и с web сервисами как оказалось то же не всё гладко. Написал сервис передаёт маленькие xml. Из за плохого интернета очень часто подвешивает платформу.
10. SinglCOOLer 213 14.03.17 11:03 Сейчас в теме
(6) Не сталкивались с такой проблемой, может у нас разная реализация, т.к. по сути дробление идет на верхнем уровне
Оставьте свое сообщение

См. также

Hello world на metadata.js Промо

Инструментарий разработчика WEB Мобильная разработка v8 1cv8.cf Абонемент ($m)

Про браузерные offline-first приложения можно написать миллионы слов. Сэкономлю своё и ваше время и перейду сразу к делу. В статье не будет рекламы и агитации за новые технологии, не будет критики традиционных или попсовых решений. Рассмотрим по шагам разработку простейшей программы на metadata.js. Постараюсь сделать акцент не на том «как это сделано», а «почему сделано именно так»

1 стартмани

11.08.2016    57115    unpete    208    

Перенос всех логов в Elasticsearch

WEB v8 Абонемент ($m)

В качестве стандартного места хранения логов в "1С:Предприятие" используется Журнал регистрации. Также часто для хранения служебных событий создают специальные Регистры сведений. Но у этих решений есть свои недостатки. В статье описан подход для хранения любых логов в самой популярной свободной поисковой системе Elasticsearch.

1 стартмани

15.07.2020    1825    kuleshov.x    4    

Выбираем российского провайдера для интеграции с WhatsApp

WEB Интеграция v8 Россия Абонемент ($m)

Собственно, почему выбираем именно провайдера и почему российского? WhatsApp, создавая свое API, преследовал две цели - делать деньги и минимизировать спам. И чтобы убить сразу двух зайцев, было принято решение предлагать API исключительно через партнеров. Ну а вопрос по поводу российского партнера скорее уже риторический. И не только из-за курса рубля, но и из-за таланта работать с российскими телефонными номерами, коим одарены далеко не все провайдеры. Между тем статья не претендует на всесторонний анализ всех возможностей всех провайдеров. Мы копнем лишь верхушку айсберга этого немаленького рынка.

1 стартмани

19.05.2020    3520    ripreal1    1    

Telegram bot API - разбор документации с примерами

WEB v8 Абонемент ($m)

Перевод документации на язык 1С.

1 стартмани

06.04.2020    30169    leongl    43    

Демо связи веб сервисов 1С и php Промо

Практика программирования Математика и алгоритмы WEB v8 1cv8.cf Абонемент ($m)

Демонстрация обращения к веб сервису 1С из php. Пример простейший, уровня hello world. Дана одна страница и информационная база 1С с одним справочником и одним веб сервисом. Веб сервис выдаёт содержимое справочника по запросу странички.

1 стартмани

19.07.2013    32018    Трактор    20    

Синтез речи из текста с помощью Яндекс SpeechKit

WEB v8 1cv8.cf Абонемент ($m)

В статье описан процесс подключения Яндекс SpeechKit API и программная реализация синтеза речи из текста с помощью этого API. Тестировалось на релизе платформы 8.3.16.1224. Может использоваться в любой конфигурации. Синтез речи может использоваться для самых разных целей, в моём случае потребовалось перевести лекции из текстовых файлов в звук

1 стартмани

05.04.2020    1577    m0zg153    2    

Вариант реализации REST API для 1С-Битрикс Управление сайтом

WEB v8 Россия Абонемент ($m)

В статье опишу вариант обмена 1С УТ 11.4 и 1С-Битрикс управление сайтом с иcпользованием компонентов Symfony, в качестве примера обмен данными по товарам.

1 стартмани

28.01.2020    4063    malikov_pro    2    

"Живые" картинки со Snap.SVG

Практика программирования WEB Работа с интерфейсом v8 Абонемент ($m)

В статье рассмотрен пример использования http-сервисов для визуализации данных

1 стартмани

24.10.2019    12919    blackhole321    7    

Примеры пользования web сервисов 1С из браузера Промо

WEB Практика программирования v8 1cv8.cf Абонемент ($m)

Даны примеры реализации доступа к web сервисам 1С из браузера. Примеры web сервисов, а также javascript'ы для доступа к этим сервисам. AJAX доступ к 1С.

1 стартмани

29.06.2008    147603    Трактор    233    

Интеграция 1С с сайтом (магазином) WordPress (WooCommerce) с помощью Rest API сайта. Часть 1. Авторизация

WEB v8 Абонемент ($m)

Интеграция 1С с сайтом (магазином) WordPress (WooCommerce) с помощью функционала Rest API предоставляемого платформой (CMS) WordPress (WooCommerce). Без дополнительных приложений на PHP/вставьте сюда любой другой язык программирования/.

1 стартмани

12.10.2019    22646    osivv    31    

АИТП. Автоматизируем управление ресурсами на примере Яндекс.Почта для домена

WEB v8 1cv8.cf Абонемент ($m)

В статье демонстрируется использование программного пакета АИТП для автоматизации предоставления ИТ-ресурсов сотрудникам на примере управления почтовыми ящиками Яндекс.Почта для домена.

1 стартмани

26.08.2019    4164    blackhole321    4    

Использование HTTP-сервиса для создания "фронтенда" HTML/CSS/jQuery с кэшированием

WEB v8 1cv8.cf Абонемент ($m)

В статье описан способ создания "фронтенда" на HTML/CSS/jQuery и скрипт кеширования AJAX запросов на PHP.

1 стартмани

06.08.2019    13459    Sedaiko    24    

Обмен с интернет-магазином на платформе DOCPART

WEB Оптовая торговля Розничная торговля Оптовая торговля Розничная торговля v8 1cv8.cf Абонемент ($m)

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

10 стартмани

04.07.2019    4578    Johny_v    14    

1C + Python + Django Rest Framework + Vue.js. Опыт несложной full-stack разработки

Практика программирования Внешние источники данных Обмен через XML WEB Разработка v8 1cv8.cf Абонемент ($m)

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

1 стартмани

22.04.2019    31423    riposte    63    

Подключение к REST API через OAuth протокол из 1С

WEB v8 1cv8.cf Абонемент ($m)

В статье описаны варианты подключения И решение граблей по подключению к REST API через протокол OAuth 2.0 из 1С. При разработке такого подключения для получения данных и загрузки в базу 1С я столкнулся с некоторыми проблемами, решил их и хочу поделиться этими наработками.

1 стартмани

06.09.2018    11767    chemezov    11    

HTTP Сервисы: Путь к своему сервису. Часть 1

Практика программирования WEB v8 1cv8.cf Абонемент ($m)

Уже много было написано про http-сервисы, но то и дело всплывают «Новые» статьи по обмену между базами V8 по COM, что «Немножко» удивляет. Решил внести свои 5 копеек, поработаем с http-сервисом.

1 стартмани

15.07.2018    78049    dsdred    24    

А чё это вы здесь делаете, а?

WEB v8 1cv8.cf Абонемент ($m)

Разработчикам тиражных обработок близка и понятна проблема обратной связи с пользователем. Много важного и полезного можно почерпнуть, зная, что делает бухгалтер, который запустил обработку. В большом мире вэба сбор статистики на сайте дело привычное и даже обязательное. Эта статья покажет практику применения инструментов сбора статистики из мира веба для обработок на платформе 1С:Предприятие.

1 стартмани

21.01.2018    23412    infosoft-v    42    

Пример заполнения/создания файла XML из XSD схемы, используя XDTO

Обмен через XML WEB v8 1cv8.cf Абонемент ($m)

Добрый день, коллеги! Наконец-то дошли руки написать сию статью. Хочу поделиться своим опытом по разбору xsd схемы используя Фабрику XDTO, а также связанным с этим XML файлом. Думаю, наверняка кому-то понадобится.

1 стартмани

21.12.2017    44590    sandybaev    24    

Получение данных из Wialon Hosting через HTTP запросы (Remote API)

WEB v8 1cv8.cf Автомобили, автосервисы Россия Абонемент ($m)

Статья будет полезна для быстрого старта работы с Wialon Hosting. Здесь я опишу основные принципы работы с системой Wialon через Remote API.

1 стартмани

12.09.2017    20964    maxopik2    20    

Google OAuth и мобильное приложение

Мобильная разработка Обмен данными 1С Внешние источники данных WEB v8 v8::Mobile 1cv8.cf Абонемент ($m)

Об аутентификации для работы с сервисами google из мобильного или настольного приложения

1 стартмани

29.08.2017    11426    stveans@gmail.com    3    

Заполнение ОГРН с использованием Инструментов разработчика

Обработка справочников WEB v8 Россия Абонемент ($m)

Вот и до нашей организации добралось требование указывать в отчетности для ГлавКонтроля ОГРН контрагента. Как всегда, задача возникла внезапно, и решить ее нужно было "вчера".

1 стартмани

14.04.2017    6583    vsuh    0    

Пошаговая инструкция настройки web-сервисов для 1Сv8.3 и IIS 8.5

Практика программирования WEB v8 1cv8.cf Абонемент ($m)

Пошаговая инструкция настройки web-сервисов для 1Сv8.3 и IIS 8.5. Windows Server 2012 R2 Standard, 1С:Предприятие 8.3 (8.3.4.465)

30.04.2014    366667    alexstey    99    

Пошаговая инструкция по созданию мобильного приложения для iOS с обменом через WEB сервисы Часть II.

Практика программирования WEB v8 Абонемент ($m)

Пошаговая инструкция по созданию мобильного приложения для iOS с обменом через WEB сервисы Часть II.

1 стартмани

16.05.2013    17946    amrec.ru    11    

Пошаговая инструкция по созданию мобильного приложения для iOS (без xcode) с обменом через WEB сервисы Часть I.

Практика программирования WEB Мобильная разработка v8 1cv8.cf Россия Абонемент ($m)

Пошаговая инструкция по созданию мобильного приложения для iOS с обменом через WEB сервисы Часть I.

1 стартмани

12.05.2013    38891    amrec.ru    26