В чем разница между Менеджером записи и Набором записей для регистров сведений в 1С и что выбрать для производительности?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке и оптимизации конфигураций на платформе 1С:Предприятие часто возникает вопрос: какой объект использовать для изменения данных в независимых регистрах сведений — МенеджерЗаписи или НаборЗаписей? На первый взгляд оба объекта позволяют записывать, изменять и удалять строки, однако внутренние механизмы платформы, взаимодействие с СУБД и поведение транзакций у них существенно различаются. Проанализируем ключевые особенности каждого подхода, разберем влияние на производительность и выясним, в каких ситуациях следует применять тот или иной объект.

Архитектурные различия и внутренние механизмы платформы

Рассмотрев поведение платформы 1С при работе с регистрами сведений, можно отметить, что МенеджерЗаписи не является принципиально отдельным механизмом хранения. Когда в программном коде создается и записывается объект МенеджерЗаписи, платформа на внутреннем уровне формирует объект НаборЗаписей с отбором по всем измерениям и периоду (ключу записи) и выполняет его сохранение.

Однако существуют важные архитектурные нюансы:

  1. Отсутствие собственного модуля: У объекта МенеджерЗаписи нет собственного модуля объекта. Все обработчики событий (такие как ПередЗаписью и ПриЗаписи) исполняются в модуле набора записей соответствующего регистра.
  2. Повторный вызов обработчиков событий: При перезаписи существующей строки через МенеджерЗаписи с изменением значений измерений платформа выполняет удаление старой записи по прежнему ключу и добавление новой. В результате этого обработчики событий модуля набора записей могут быть вызваны повторно.
  3. Подписки на события: В случае применения НаборЗаписей подписки на события срабатывают один раз на весь набор. Если же выполняются операции над несколькими объектами МенеджерЗаписи, подписки и события модуля вызываются отдельно для каждого менеджера.

Взаимодействие с СУБД: транзакции и SQL-запросы

Посмотрим на то, как запись данных происходит на уровне системы управления базами данных (СУБД). Процесс записи набора строк состоит из следующих шагов:

  1. Очистка старых данных: Если набор записывается в режиме замещения по умолчанию (параметр Замещать = Истина), платформа сначала отправляет запрос DELETE для удаления существующих записей, подпадающих под установленный Отбор.
  2. Вставка новых строк: Попадающие в набор строки вставляются с помощью отдельных SQL-инструкций INSERT для каждой записи.
  3. Запись без замещения: Если вызывать метод Записать(Ложь), этап удаления DELETE пропускается, и платформа сразу переходит к выполнению команд INSERT.

Главная разница в производительности заключается в управлении транзакциями:

При использовании объекта НаборЗаписей операции удаления и вставки всей группы строк автоматически оборачиваются платформой в одну транзакцию СУБД. При попытке записать множество строк поочередно через МенеджерЗаписи без явного управления транзакциями платформа будет открывать и фиксировать транзакцию для каждой строки отдельно. Это создает колоссальную нагрузку на дисковую подсистему и сервер базы данных.

Если требуется записать несколько менеджеров записи, их обязательно следует обернуть в явную транзакцию:


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

Для Каждого СтрокаДанных Из МассивДанных Цикл
    МенеджерЗаписи = РегистрыСведений.МойРегистр.СоздатьМенеджерЗаписи();
    ЗаполнитьЗначенияСвойств(МенеджерЗаписи, СтрокаДанных);
    МенеджерЗаписи.Записать();
КонецЦикла;

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

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

Выясним, какие риски и преимущества несут в себе оба объекта с точки зрения защиты данных и параллельной работы пользователей.

Безопасность кода: Набор записей требует внимательного отношения к отборам. Если создать объект НаборЗаписей, не установить у него Отбор и вызвать метод Записать() (или Записать(Истина)), платформа полностью очистит содержимое всего регистра сведений. Объект МенеджерЗаписи лишен этого риска, так как он адресно работает с одной записью по ключевым полям.

Управляемые блокировки: МенеджерЗаписи накладывает точечную блокировку исключительно на конкретный ключ записи (все измерения и период). НаборЗаписей блокирует диапазон данных, определенный отбором. Если отбор установлен не по всем измерениям, блокируется группа данных, что может приводить к ожиданиям на блокировках при параллельной работе нескольких сеансов.

Практический пример: оптимальная пакетная запись

Разберем пример эффективной записи большого массива данных в регистр сведений с использованием объекта НаборЗаписей. Для достижения максимальной производительности рекомендуется разбивать данные на пакеты (например, по 1000–5000 строк) и записывать их без предварительного удаления (если гарантировано отсутствие дублей по ключу):


НаборЗаписей = РегистрыСведений.МойРегистр.СоздатьНаборЗаписей();

Счетчик = 0;
Для Каждого СтрокаИсточник Из ТаблицаИсточника Цикл

    НоваяЗапись = НаборЗаписей.Добавить();
    ЗаполнитьЗначенияСвойств(НоваяЗапись, СтрокаИсточник);

    Счетчик = Счетчик + 1;

    // Записываем порциями по 1000 строк
    Если Счетчик % 1000 = 0 Тогда
        // Замещать = Ложь отключает выполнение команды DELETE перед вставкой
        НаборЗаписей.Записать(Ложь);
        НаборЗаписей.Очистить();
    КонецЕсли;

КонецЦикла;

// Записываем остаток
Если НаборЗаписей.Количество() > 0 Тогда
    НаборЗаписей.Записать(Ложь);
    НаборЗаписей.Очистить();
КонецЕсли;

Резюме и рекомендации по выбору

Сводя воедино особенности обоих объектов, сформируем рекомендации по их применению:

← На главную