Как разбить большой объем данных на несколько документов для избежания блокировок?

Разбиение большого объёма данных на несколько документов — один из наиболее эффективных подходов к уменьшению нагрузки на систему 1С и СУБД, снижению вероятности конфликтов блокировок и повышению стабильности при массовых операциях. Особенно это актуально, когда количество строк в одном документе достигает десятков или сотен тысяч, что приводит к большим транзакциям, блокировке таблиц регистров, переполнению памяти и другим проблемам.

Когда нужно разбивать данные на несколько документов

  • Если объём данных превышает 5–10 тыс. строк в одном документе.

  • При массовой записи в регистры (накопления, бухгалтерии).

  • При генерации документов за длительный период (например, за год по дням).

  • Когда наблюдаются ошибки «недостаточно памяти» или падения производительности.

  • Если пользователи жалуются на тормоза при открытии/проведении документов.

Как реализовать разбиение

1. Выбор критерия разбиения

В зависимости от типа данных, выбирается логика группировки:

  • По дате (день, неделя, месяц).

  • По организации.

  • По складу, подразделению, проекту и т.п.

  • По количеству строк (например, не более 1000 в одном документе).

  • По ключевому полю (например, контрагент, заказ).

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

2. Подготовка таблицы значений или выборки для пакетной обработки

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

Запрос.Текст = "ВЫБРАТЬ ... ИЗ ...";
Результат = Запрос.Выполнить().Выгрузить();

Результат — таблица значений или массив, который затем нужно группировать.

3. Группировка по выбранному критерию

Разделяем данные по критерию:

Для Каждого Строка Из Результат Цикл
Ключ = Строка.Дата; // или другой признак
Если Не КартаДокументов.СодержитКлюч(Ключ) Тогда
Док = Документы.ПоступлениеТоваров.СоздатьДокумент();
Док.Дата = Ключ;
Док.Товары.Очистить();
КартаДокументов.Вставить(Ключ, Док);
КонецЕсли;
Док = КартаДокументов\[Ключ\];
НоваяСтрока = Док.Товары.Добавить();
НоваяСтрока.Номенклатура = Строка.Номенклатура;
НоваяСтрока.Количество = Строка.Количество;
КонецЦикла;

Или использовать ГруппироватьПоЗначению или Сгруппировать() для массивов/таблиц.

4. Ограничение по количеству строк

Если критерий не позволяет равномерно разбить данные (например, все на одну дату), нужно считать строки и создавать новый документ каждые N записей:

МаксСтрок = 1000;
Счетчик = 0;
Для Каждого Строка Из Результат Цикл
Если Документ = Неопределено Или Счетчик >= МаксСтрок Тогда
Если Документ <> Неопределено Тогда
Документ.Записать(РежимЗаписиДокумента.Проведение);
КонецЕсли;
Документ = Документы.ПоступлениеТоваров.СоздатьДокумент();
Документ.Товары.Очистить();
Счетчик = 0;
КонецЕсли;
НоваяСтрока = Документ.Товары.Добавить();
// заполнение полей
Счетчик = Счетчик + 1;
КонецЦикла;
Если Документ <> Неопределено Тогда
Документ.Записать(РежимЗаписиДокумента.Проведение);
КонецЕсли;

5. Проведение и контроль транзакций

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

  • Можно обернуть Документ.Записать() в Попытка/Исключение, чтобы логировать ошибки и продолжать выполнение.

  • При критичных ошибках (например, некорректные ссылки) можно писать лог и пропускать документ.

6. Параллельная обработка

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

  • Использовать фоновые задания.

  • Вызывать обработку из планировщика по разным группам данных.

  • Главное — следить, чтобы параллельные задачи не конкурировали за одни и те же регистры или объекты.

Примеры реальных кейсов

  • Разделение документа «Реализация товаров» по складам: один склад — один документ.

  • Формирование актов по каждому контрагенту в отдельном документе.

  • Загрузка банковских выписок — один документ на каждую дату.

  • Проведение инвентаризации — один документ на каждое помещение.

Дополнительные меры

  • Создать отдельную внешнюю обработку для выполнения пакетной записи.

  • Вести лог — сколько строк обработано, сколько документов создано, сколько ошибок.

  • При повторном запуске можно проверять, какие данные уже были записаны, чтобы избежать дублирования.

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