Например, посмотрим регистры накопления:
- ЗаданияНеоперативногоДопроведенияДокументов
- ДенежныеСредстваБезналичные
В модулях менеджера которых есть процедура "ЗарегистрироватьДанныеКОбработкеДляПереходаНаНовуюВерсию", в которой выполняется выборка данных.
Затем эта выборка, в качестве ТЗ или массива уходит в процедуру ОбновлениеИнформационнойБазы.ОтметитьКОбработке"
Самое забавное, что 1С для нас (но, видимо, не для себя) написали комментарий к процедуре
"ОтметитьКОбработке"
// Отмечает, что переданные данные необходимо обновить.
// Важно: не рекомендуется передавать в параметр Данные сразу все данные, которые
// необходимо зарегистрировать к обработке, т.к. большие коллекции типа Массив
// или ТаблицаЗначений могут занять существенный объем памяти сервера и привести
// к сильному снижению производительности системы. Рекомендуется получать и передавать
// данные небольшими порциями, например по 1000 объектов.
Это отлично .. но при этом в обработчике обновлений ... мы получаем огромную выборку .. без каких-либо разделений на порции.. в после передачи этой выборки (массив или ТЗ) в "ОтметитьКОбработке".. даже на мощных серверах .. мы просто падаем ...
Выход:
1) Создаем общий модуль "РаботаСПорциямиСервер" (Сервер, внешнее соединение)
Код модуля:
#Область ПрограммныйИнтерфейс
Функция РазбитьМассивНаПорции(ВходящийМассив, РазмерПорции) Экспорт
ПулМассивов = Новый Массив;
МассивПорция = Новый Массив;
Если ВходящийМассив.Количество() <= РазмерПорции Тогда
ПулМассивов.Добавить(ВходящийМассив);
Возврат ПулМассивов;
КонецЕсли;
Для Индекс = 0 По ВходящийМассив.ВГраница() Цикл
Если МассивПорция.Количество() = РазмерПорции Тогда
ПулМассивов.Добавить(МассивПорция);
МассивПорция = Новый Массив;
КонецЕсли;
МассивПорция.Добавить(ВходящийМассив.Получить(Индекс));
КонецЦикла;
Если Индекс -1 = ВходящийМассив.ВГраница() И МассивПорция.Количество() <> 0 Тогда
ПулМассивов.Добавить(МассивПорция);
КонецЕсли;
Возврат ПулМассивов;
КонецФункции
Функция РазбитьТЗНаПорции(Тз, РазмерПорции) Экспорт
ПулМассивов = Новый Массив;
Если Тз.Количество() <= РазмерПорции Тогда
ПулМассивов.Добавить(Тз);
Возврат ПулМассивов;
КонецЕсли;
ТзПорция = ПустаяТз(Тз);
Для Сч = 0 По Тз.Количество() -1 Цикл
Если ТзПорция.Количество() = РазмерПорции Тогда
ПулМассивов.Добавить(ТзПорция);
ТзПорция = ПустаяТз(Тз);
КонецЕсли;
НоСтрокаТз = ТзПорция.Добавить();
ЗаполнитьЗначенияСвойств(НоСтрокаТз, Тз.Получить(Сч));
КонецЦикла;
Если Сч = Тз.Количество() И ТзПорция.Количество() <> 0 Тогда
ПулМассивов.Добавить(ТзПорция);
КонецЕсли;
Возврат ПулМассивов;
КонецФункции
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Функция ПустаяТз(Тз)
Возврат Тз.СкопироватьКолонки();
КонецФункции
#КонецОбласти
Исправление в расширении выглядит так:
#Удаление
ОбновлениеИнформационнойБазы.ОтметитьКОбработке(
Параметры, Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Регистратор"), ДополнительныеПараметры);
#КонецУдаления
#Вставка
РазмерПорции = 500;
ДанныеДляОбработки = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Регистратор");
ПулМассивовДляОбработки = РаботаСПорциямиСервер.РазбитьМассивНаПорции(ДанныеДляОбработки, РазмерПорции);
Для Каждого ЭлМассива Из ПулМассивовДляОбработки Цикл
ОбновлениеИнформационнойБазы.ОтметитьКОбработке(Параметры, ЭлМассива, ДополнительныеПараметры);
КонецЦикла;
#КонецВставки
После таких доработок, отложенные обработчики отработают штатно, и проблем возникать не будет.
PS все это справедливо для "больших баз", где первички очень много...
Вступайте в нашу телеграмм-группу Инфостарт