Специализированные параметры фонового задания имеют слишком большой размер
Фоновые задания: быстро получить большие данные в 1С
Вводная
Представим, что нужно периодически запрашивать какой-то большой объем данных из внешней системы, но повлиять на скорость ответа внешнего сервиса/системы мы не можем, а очень хочется получать данные быстро. При этом открыть несколько параллельных сеансов внешняя система не запрещает. Тогда на помощь приходят они ФоновыеЗадания 1С в серверной базе (в файловой базе выигрыша в скорости не происходит).
Увеличение скорости происходит не линейно и максимально мне удавалось достичь ускорения за счет параллельности максимум в 3-5 раз от скорости в 1 сеансе. Это происходит из-за того, что тратятся ресурсы и время на создание параллельных сеансов, а потом на ожидание и сборку результатов.
Чтобы достичь максимального эффекта для конкретной задачи приходится опытным путем в песочнице определять:
В 1С теоретически можно создать сколь угодно много фоновых заданий, нО. внешняя система либо может не выдержать такой нагрузки, либо просто забанит нас. Потому рекомендую программно ставить ограничение в 1С не более 10-30 одновременных потоков.
Алгоритм действий:
Объекты метаданных которые понадобятся для решения:
В общем модуле нам достаточно 1 экспортной процедуры, куда передается на вход сформированный ранее в обработке текст запроса и идентификатор фонового задания для записи промежуточного результата работы процедуры в РегистрСведений с этим же идентификатором.
Вспомогательные процедуры/функции и другие выполняющие собственно саму работу процедуры для настоящей статьи не существенны и могут меняться в зависимости от задачи. Имеются в приложенном файле конфигурации.
В обработке запуска фоновых заданий получаем из внешней системы или придумываем свой уникальный идентификатор, по которому будем бить задачи на порции. В примере для ADS берем выборку ключевого поля из нужной таблицы и потом разбиваем полученный результат на структуру, содержащую массивы порционных ключей таблицы.
Если установили ограничение на максимальное количество одновременных фоновых заданий, то в цикле запуска фоновых заданий останавливаемся при достижении лимита, ждем завершения ранее созданных заданий, собираем промежуточные результаты и только потом двигаемся дальше.
Вызов фоновых заданий выполняется в цикле через метод ФоновыеЗадания.Выполнить(), который выполнит сделанную ранее в общем модуле экспортную процедуру. Фоновому заданию передается: ИмяОбщегоМодуля.ИмяЭкспортнойПроцедуры, массив параметров и идентификатор фонового задания, по которому потом будем собирать данные из РегистраСведений.
На выходе получаем результирующие данные из параллельных фоновых заданий.
В заключение
Все примеры и листинги сделаны как эмуляция заполнения массивов и таблиц значений, а если прописать настоящий адрес, ключевое поле и имя таблицы и выключить эмуляцию, то работает с Advantage Database Server (далее – ADS), СУБД понимающей стандартный язык запросов T-SQL через Com объекты ADODB. Алгоритм можно использовать в любых похожих ситуациях с любыми СУБД, внешними службами, когда требуется ускорить/распарралелить вычисления.
В прилагаемом к статье файле конфигурация с 3 объектами для работы с ФоновымиЗаданиями 1С, включая все необходимые вспомогательные и служебные процедуры, функции, чтобы не зависеть от БСП и типа, версии конфигурации. Легко добавить в любую конфигурацию, если есть возможность изменения или как расширение и затем быстро подкорректировать под свою задачу. Формы Регистра и Обработки управляемые. Версия Платформы требуется не ниже 8.3.13, конфигурация любая.
Как передать в фоновое задание большую таблицу значений (12 млн записей)
такую таблицу проще затолкать в таблицу скуля и обработать там, если она на куски не рубится
Лучше придумать другой алгоритм «диспетчерзиации» задач между запущенными заданиями. Так, чтобы не требовалось гонять половину базы в оперативной памяти (а это и происходит при передаче параметров фонового задания).
>И не совсем понятно как объектные сущности в таблице значений разложить в таблице SQL много шаманства по моему будет
мы не в курсе накой черт тебе 12 лямов записей
>Как эта ТЗ формируется? Очень сложно?
либо тз с хз и в временный файл.
было не так давно в одной отраслевой упп.
модуль проведение документа.
внутри 2-го обход ТЧ и набивание ТЗ построчно.
теперь простая арифметика:
ТЗ = 10 000 000 строк
клиент «думает» до 2 Гб и падает
что делает клиент? звонит во франь, консультант франя заходит по rdp на сервак и (о чудо!) проводит документ. За 10 минут. Сервак 64-бит. А значит 3,5 Гб на клиента скребя ложкой по дну ему хватает.
какой вывод сделал франь?
купите 64-бит сервер 1с.
(38) При положении в ХЗ пойдет сериализация в XDTO + кодирование в base64, которое, я боюсь, выполнено через опу..
При извлечении из ХЗ пойдет обратный процесс.
(31) распараллеливается запись одного набора?
и в наборе 12 миллионов строк?
что-то я не очень понял.
странно что все пытаются придумать что делать с тз, вместо того, чтобы удостовериться в том, что в принципе выбрана правильная методика решения задачи.
(60) Все такие умные, что ППЦ.
А мы тут про расчет себестоимости.
(61)
Исследования методом «научного тыка» показали.
Для каждого типа делалась попытка:
(68) Масштабно, епта.
Результаты опубликуй.
ТЗ В XDTO есть? Нет? А если найду?!
(68) Дааа, ты чертовски прав..
1) Создал справочник с реквизитом ХЗ.
Простите за кодировку, было лениво морочиться.
К тому же, даже из вашей ссылки на вики:
> По замыслу разработчиков сначала должна быть описана
> структура данных, которая затем компилируется в классы,
Т.е. опять-таки нет речи о том, чтобы просто взять кусок оперативной памяти и зафигачить в файл (а потом просто прочитать из файла).
На основании объекта класса строится DTO-представление, которое уже и пишется файл.
Мегазадача. а если попробовать как-то получать из разных сеансов адрес ячеек в ОЗУ, занятых исходной таблицей (которую инициировал родительский сеанс)?
Можно создавать локальные и глобальные временные таблицы. Локальные временные таблицы видимы только во время текущего сеанса, а глобальные — во всех сеансах. Временные таблицы не подлежат секционированию.
Имени локальной временной таблицы должен предшествовать знак номера (#table_name), а имени глобальной временной таблицы — двойной знак номера (##table_name).
Инструкции SQL могут обращаться к временной таблице по заданному в инструкции CREATE TABLE значению аргумента table_name, например:
Длительные операции на сервере
Область применения: управляемое приложение.
1. При разработке конфигураций следует избегать длительных вызовов из клиентского кода в серверный. Все длительные серверные вызовы, которые могут выполняться более 8 секунд в обычных сценариях работы пользователя, следует выполнять асинхронно, с помощью фонового задания.
К таким операциям относятся: формирование отчета, групповая обработка объектов, загрузка или выгрузка данных в другое приложение, заполнение больших табличных частей и т.п.
В противном случае такие вызовы могут привести к потере работоспособности приложения или затруднению работы с ним:
2.1. Общий подход к асинхронному выполнению длительных серверных операций с помощью фонового задания:
а для прочих мест – выводится блокирующая форма ( РежимОткрытияОкна = БлокироватьОкноВладельца ), на которой размещена декорация с анимированной картинкой и кнопка «Отмена» :
2.2. Асинхронное формирование отчета требуется только для тех отчетов, которые
Поведение таких отчетов должно быть максимально похожим на поведение отчетов на базе СКД, а именно:
Пример выполнения функции в фоновом задании при использовании в конфигурации Библиотеки стандартных подсистем. В модуле менеджера объекта размещена функция, которая выполняет поиск настроек и возвращает их:
Функция ОпределитьНастройкиУчетнойЗаписи(АдресЭлектроннойПочты, Пароль) Экспорт
.
Возврат Настройки;
КонецФункции
В форме объекта выполняется вызов этой функции в фоновом задании в три этапа:
1) запуск фонового задания на сервере,
2) подключение обработчика завершения фонового задания на клиенте,
3) обработка результата выполнения фонового задания.
// 2. Подключение обработчика завершения фонового задания.
ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
Оповещение = Новый ОписаниеОповещения(«ПриЗавершенииПоискаНастроек», ЭтотОбъект);
ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация, Оповещение, ПараметрыОжидания);
КонецПроцедуры
// 3. Обработка результата выполнения фонового задания.
&НаКлиенте
Процедура ПриЗавершенииПоискаНастроек(Результат, ДополнительныеПараметры) Экспорт
Если Результат = Неопределено Тогда // Пользователь отменил задание.
Возврат;
КонецЕсли;
Если Результат.Статус = «Ошибка» Тогда
ВызватьИсключение Результат.КраткоеПредставлениеОшибки;
КонецЕсли;
Настройки = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);
УдалитьИзВременногоХранилища(Результат.АдресРезультата);
УстановитьНастройкиУчетнойЗаписи(Настройки);
Методическая рекомендация (полезный совет)
3.1. При каждом выполнении фонового задания его результат помещается во временное хранилище на время жизни формы:
ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияФункции(УникальныйИдентификатор);
ДлительныеОперации.ВыполнитьФункцию(ПараметрыВыполнения, ПараметрФоновогоЗадания);
Если длительная операция выполняется пользователем многократно, пока эта форма открыта, то временные хранилища накапливаются, что вызывает рост потребления памяти. Поэтому для уменьшения расхода оперативной памяти в большинстве случаев рекомендуется очищать временное хранилище сразу после получения результата фонового задания:
Настройки = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);
УдалитьИзВременногоХранилища(Результат.АдресРезультата); // Данные во временном хранилище больше не требуются.
Если же результат фонового задания требуется сохранять на протяжении нескольких серверных вызовов, то необходимо передавать фиксированный адрес заранее инициализированного временного хранилища:
Возврат ДлительныеОперации.ВыполнитьФункцию(ПараметрыВыполнения,
«Справочники.УчетныеЗаписиЭлектроннойПочты.ОпределитьНастройкиУчетнойЗаписи»,
АдресЭлектроннойПочты, Пароль);
КонецФункции
4. Если в конфигурации реализуются алгоритмы, инициирующие запуск фоновых заданий или запись данных информационной базы без участия пользователя (например, регулярное обновление информации в открытой форме), то в них следует проверять, что в текущем сеансе не установлен монопольный режим. В противном случае, следует блокировать попытки выполнения таких действий. Например:
Если МонопольныйРежим() Тогда
Возврат;
КонецЕсли;
5. В некоторых случаях возникает необходимость в выполнении длительных операций, требующих установки монопольного режима доступа к информационной базе. Например:
При этом необходимо сначала устанавливать монопольный режим, а затем выполнять запуск фонового задания, которое реализует саму длительную операцию. В этом случае фоновым заданием будет унаследован монопольный режим, ранее установленный из пользовательского сеанса (см. документацию к платформе).
На время выполнения этого фонового задания следует блокировать весь интерфейс приложения, открывая форму ожидания завершения операции в режиме РежимОткрытияОкна = БлокироватьВесьИнтерфейс. Блокировать интерфейс приложения требуется потому, что на время выполнения задания полноценная работа пользователя с приложением уже невозможна:
* Примечание: ошибки записи также возникают в тех случаях, когда объекты записываются программно, например, из обработчиков ожидания. В них также следует проверять монопольный режим согласно п.5.
Слишком много фактических параметров
Ошибка в 1С 8.3 Слишком много фактических параметров указывает, что при выполнении операции в процедуру ее обработки переданы лишние параметры. Поскольку не всегда это вызвано ошибками программного кода, проблема серьезнее, чем кажется на первый взгляд.
Эксперты БухЭксперт8 подготовили подробный разбор причин появления ошибки и рекомендации по их устранению.
Причины ошибки
Среди причин появления ошибки Слишком много фактических параметров :
В окне ошибки, как правило, отображается полная информация о месте возникновения ошибки и наименовании модуля, в котором она произошла.
Получите понятные самоучители 2021 по 1С бесплатно:
Но не спешите сразу открывать Конфигуратор. Ознакомьтесь с информацией ниже, которая поможет исключить одни действия и обратить внимание на другие при работе с ошибкой.
Ошибка обновления конфигурации
Если ошибка Слишком много фактических параметров появилась сразу после обновления конфигурации 1С на новый релиз, есть высокая вероятность, что она связана с новым релизом.
В этом случаи ваши действия:
Восстановите базу из копии или попросите обслуживающую фирму исправить ошибку программного кода.
Ошибка обновления Платформы
При обновлении конфигурации важно читать информацию из файла README.TXT, в котором указывается желательная версия Платформы 1С для работы с новой конфигурацией.
В практике Бухэксперт8 были ситуации, когда ошибка «лечилась» именно установкой рекомендованной Платформы 1С, поэтому важно обратить на это внимание.
Динамическое обновление конфигурации
При динамическом обновлении конфигурации вносятся несущественные доработки в программный код при работающих пользователях.
В результате у работающего пользователя может запомниться старый кэш с наиболее часто используемыми процедурами и функциями программы. Если при обновлении в программный код какой-то функции или процедуры добавили новые параметры, появится рассогласование новых данных обновления и параметров в старом кеше. Это приведет к появлению ошибок.
Ситуация небезнадежная: как правило, она легко решается чисткой кеша.
Ошибка в программном коде
В окне ошибки указаны:
Как видно из приведенных выше, данных:
После удаления лишней запятой в процедуре ПодборНоменклатуры число фактических параметров в функции ПолучитьПараметрыПодбора будет соответствовать числу описываемых параметров этой функции.
Ошибка при открытии документов Поступление (акт, накладная) больше не появится.
См. также:
Если Вы еще не являетесь подписчиком:
После оформления подписки вам станут доступны все материалы по 1С Бухгалтерия, записи поддерживающих эфиров и вы сможете задавать любые вопросы по 1С.
Получите еще секретный бонус и полный доступ к справочной системе БухЭксперт8 на 14 дней бесплатно
Похожие публикации
Карточка публикации
(1 оценок, среднее: 5,00 из 5)
Добавить комментарий Отменить ответ
Для отправки комментария вам необходимо авторизоваться.
Вы можете задать еще вопросов
Доступ к форме «Задать вопрос» возможен только при оформлении полной подписки на БухЭксперт8
Нажимая кнопку «Задать вопрос», я соглашаюсь с
регламентом БухЭксперт8.ру >>
Здравствуйте! Ежегодно подписываюсь на ваши рубрикаторы, ваша квалифицированная поддержка дает опору и уверенность, что все новшества в законодательстве будут внедрены и решаемы поставленные задачи. Спасибо за ваш вклад в нас бухгалтеров.
Запуск фонового задания во внешней обработке без регистрации в справочнике «Дополнительные отчеты и обработки»
Уже опубликовано немало способов отобразить прогресс выполнения во внешней обработке, но все они (по крайней мере те, что я нашел), требуют подключения внешней обработки к справочнику дополнительных отчетов/обработок в составе конфигурации.
Мне же нужно было показать прогресс выполнения, не подключая обработку к этому справочнику.
В качестве базового шаблона для решения моей задачи я использовал пример, опубликованный здесь: https://wiki.programstore.ru/zapusk-fonovogo-zadaniya-vo-vneshnej-obrabotke-s-indikaciei/
Важное замечание
Этот пример рассчитан на работу в двух вариантах:
1. Без подключения к подсистеме внешних отчетов/обработок;
2. С подключением к подсистеме.
Для тех, кто решает подобную проблему впервые, описываю принцип работы этого примера. В конце прикрепил файл внешней обработки, которую можно использовать в качестве шаблона.
Модуль объекта внешней обработки
На случай, если вы планируете подключать обработку к подсистеме внешних отчетов/обработок, я оставил экспортный метод «СведенияОВнешнейОбработке».
За реализацию длительной операции отвечает экспортный метод «ДлительнаяОперация», в которой организовано заполнение массива по тысяче строк, а в первом параметре передается количество таких заполнений (итераций). Рекомендую устанавливать количество итераций от 10 000.
Модуль формы внешней обработки
На форму добавлен собственный индикатор и строка состояния, а также реквизит «Количество итераций» и кнопка запуска длительной операции. В этом примере прогресс работает достаточно наглядно, если количество итераций от 10 000.
Подготовка данных для длительной операции
Обратите внимание на код процедуры «ПодготовитьДанныеДляДлительнойОперации»:
1. Если обработка подключена к подсистеме внешних отчетов/обработок, то в нее при создании передана ссылка на справочник доп. отчетов/обработок, и параметры готовятся так, чтобы запустить подключенную в подсистему обработку;
2. Если же обработка не подключена к подсистеме, то определяется имя файла этой обработки, а ссылка устанавливается пустая.
Обработчик команды «ЗапуститьВыполнение»
Выполняется при нажатии на кнопку «Запустить выполнение», и выполняет следующие действия:
1. Обнуляет индикатор прогресса;
2. Создает фоновое задание и запоминает его идентификатор в реквизите формы;
3. Подключает обработчики ожидания, отвечающие за обновление прогресса.
В этом примере используется отображение и через индикатор на форме, и через стандартное окно отображения состояния. Я бы не рекомендовал отключать стандартное окно, так как в нем есть кнопка «Отмена», которая позволяет прервать исполнение длительной операции.
Когда длительная операция завершится, будет исполнен клиентский метод формы «ФоновоеЗаданиеЗавершение».
Здесь мы в первую очередь отключаем обработчик ожидания, который отвечает за обновление индикатора, а потом анализируем результат выполнения фонового задания. Если задание завершилось с ошибкой, можно организовать выполнение длительной операции без отображения индикатора. Для этого нужно вызвать экспортный метод объекта обработки «ДлительнаяОперация», передав в него исходные данные самостоятельно.
2. В исходном примере «ДополнительнаяОбработкаСсылка» всегда была заполнена ссылкой на подключенную к подсистеме внешнюю обработку.
У меня это либо пустая ссылка (если не было подключения к подсистеме), либо ссылка на подключенную обработку.
Вот, собственно, и все.
Надеюсь, что эта статья поможет разобраться с проблемой отображения состояния длительной операции тем, кто такую проблему еще не решал.
Кроме того, эту ссылку могу использовать и я сам, не так ли? ))