Режимы удаления движений в 1С: в каких случаях что выбирать и как избежать блокировок БД

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

При проектировании документов в платформе 1С:Предприятие разработчик сталкивается с выбором свойства Удаление движений. От этого параметра напрямую зависят скорость проведения документов, вероятность возникновения мертвых блокировок (deadlocks) и устойчивость системы при высокой параллельной нагрузке.

Разберем детально, чем отличаются варианты настройки, почему в типовых решениях (УТ 11, ERP, КА) преобладает режим Не удалять автоматически, и как правильно организовать работу с движениями в коде.

Сравнение режимов работы с движениями

Платформа 1С предлагает три основных режима очистки записей регистров:

  1. Удалять автоматически — платформа принудительно очищает абсолютно все движения документа по всем составным регистрам перед вызовом обработчика ОбработкаПроведения, а также при отмене проведения.
  2. Удалять при отмене проведения — платформа автоматически очищает движения только при вызове отмены проведения документа. При перепроведении старые движения не удаляются отдельной операцией, а перезаписываются поверх при включенном свойстве Замещение = Истина.
  3. Не удалять автоматически — платформа полностью перекладывает управление движениями на разработчика. Очистка и запись данных выполняются только из программного кода.

Почему режим «Удалять при отмене проведения» эффективнее автоматического

Рассмотрим, что происходит на уровне СУБД при перепроведении документа. В стандартном автоматическом режиме система сначала делает команду DELETE для всех регистров из состава движений, а затем команду INSERT для новых записей. Это создает две фазы обращения к СУБД и удлиняет транзакцию.

Если выбрать режим Удалять при отмене проведения, платформа при повторном проведении выполняет перезапись наборов записей. Операция записи набора с включенным флагом Замещение заменяет старые данные за одно обращение к БД. Это снижает объем журнала транзакций и сокращает время блокировки таблиц.

Причины выбора режима «Не удалять автоматически» в крупных конфигурациях

Проанализируем, почему в современных конфигурациях разработчики массово отказываются даже от режима Удалять при отмене проведения в пользу полностью ручного управления Не удалять автоматически:

  1. Исключение избыточных блокировок по «пустым» регистрам. Если документ указан в составе движений регистра, но по логике проведения конкретного экземпляра записи в этот регистр не формируются, автоматический механизм платформы все равно пытается очистить по нему данные. СУБД выполняет поиск записей по регистратору. При отсутствии необходимых индексов или при высокой параллельной нагрузке это может вызвать эскалацию блокировки (переход от блокировки строк к блокировке всей таблицы регистра). В итоге блокируются пользователи, работающие с совершенно другими документами.
  2. Возможность выборочной перезаписи регистров. При перепроведении крупных документов (например, реализаций или поступлений) не всегда нужно пересчитывать абсолютно все регистры. В режиме Не удалять автоматически можно программно очистить и сформировать движения только по избранным регистрам, не затрагивая остальные, что значительно ускоряет работу.
  3. Сохранение контекста старых движений при отмене проведения. При автоматической отмене проведения движения стираются платформой до входа в обработчик ОбработкаУдаленияПроведения. Если бизнес-логика отмены требует сначала прочитать прежние движения документа (например, для корректировки связанных подчиненных записей или логирования), при автоматическом режиме сделать это невозможно. Режим Не удалять автоматически оставляет старые записи доступными для чтения внутри алгоритма.
  4. Предотвращение временных «дыр» в остатках. При автоматической очистке между удалением старых записей и записью новых проходит время расчетов. Если в этот момент другой пользователь выполняет оперативный контроль остатков, он может получить искаженные данные. При ручном замещении набора этот временной разрыв отсутствует.
  5. Точечное управление управляемыми блокировками. Разработчик получает возможность явно установить БлокировкаДанных исключительно на те комбинации измерений, которые реально меняются документом.

Правильная программная реализация при режиме «Не удалять автоматически»

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

В обработчике отмены проведения в модуле объекта документа нужно явно прописать очистку наборов записей регистров:


Процедура ОбработкаУдаленияПроведения(Отказ)
    
    // Очищаем движения по необходимым регистрам
    Движения.ТоварыНаСкладах.Записать();
    Движения.Взаиморасчеты.Записать();
    
КонецПроцедуры

Разберем важные детали этой операции:

  1. Метод Записать() для не заправленного данными набора записей с установленным по умолчанию свойством Замещение = Истина очищает все движения документа по данному регистру.
  2. Для предотвращения взаимных блокировок (deadlocks) при параллельной работе пользователей очистку и запись движений по нескольким регистрам следует выполнять всегда в одном и том же порядке (например, по алфавиту имен регистров) во всех документах системы.
← На главную