Зачем записывать движения в регистр перед проверкой остатков в 1С

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

В современной разработке на платформе 1С:Предприятие 8.3 часто возникает вопрос: почему общепринятым стандартом стало сначала записывать данные в регистр накопления, а уже затем проверять наличие отрицательных остатков? На первый взгляд, это кажется нелогичным: зачем совершать лишнее действие записи, если товара может не хватить? Однако за этим подходом, известным как «новая методика проведения», стоят серьезные требования к производительности, масштабируемости и корректности работы в многопользовательской среде. Разберем эту тему подробно.

Исторический контекст: Старая vs Новая методика

Проанализируем путь развития механизмов проведения. В старых типовых конфигурациях (например, «Управление производственным предприятием» или «Управление торговлей 10.3») использовалась так называемая старая методика. Ее суть заключалась в том, что программа сначала рассчитывала «прогнозный» остаток (текущий остаток минус то, что мы хотим списать) и, если результат был положительным, записывала движения.

В современных решениях, таких как 1С:ERP или Управление торговлей 11, применяется новая методика. Здесь мы сначала фиксируем факт списания в базе данных (внутри транзакции), а потом одним простым запросом проверяем — не ушел ли остаток в «минус». Если ушел — транзакция отменяется (откатывается).

Причина 1: Оптимизация работы СУБД (SQL-запросы)

Рассмотрим, как видит наши действия сервер базы данных. При использовании старой методики нам нужно выполнить запрос, в котором происходит соединение временной таблицы (товары из документа) с виртуальной таблицей остатков. Для СУБД (например, MS SQL Server или PostgreSQL) это сложный запрос с точки зрения построения плана выполнения. Необходимо сопоставить данные в памяти с данными на диске, учитывая множество условий.

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

  1. Мы записываем движения. Это простая операция вставки (Insert) или обновления записей.
  2. Мы выполняем запрос к таблице остатков только по тем товарам, которые были в документе.

Запрос в новой методике максимально прост: ВЫБРАТЬ ... ИЗ Регистр.Остатки ГДЕ КоличествоОстаток < 0. СУБД выполняет такой запрос молниеносно, так как ей не нужно делать сложные соединения (Join) с данными документа — данные уже находятся «внутри» регистра (хоть и не зафиксированы окончательно).

Причина 2: Управляемые блокировки и параллельность

Разберем ситуацию, когда несколько пользователей одновременно проводят документы по одному и тому же товару. Выясним, почему это критично. В системе 1С используется механизм управляемых блокировок. Чтобы данные остатков не изменились другими пользователями в процессе нашего проведения, мы должны «заблокировать» нужные нам записи.

В новой методике блокировка данных происходит в момент записи движений. Это позволяет минимизировать время, в течение которого другие пользователи ждут доступа к этим ресурсам. Проанализируем цепочку событий:

  1. Запись пустых наборов (очистка старых движений) и установка блокировки.
  2. Расчет себестоимости и формирование новых движений.
  3. Запись новых движений (фиксирование намерения списать товар).
  4. Проверка остатков.

Если мы сначала проверим, а потом запишем, возникает риск «фантомных остатков»: два пользователя одновременно увидели, что на складе есть 1 шт. товара, оба решили, что им хватает, и оба записали списание. В итоге остаток станет -1. Новая методика исключает это на уровне архитектуры: запись происходит раньше проверки, и за счет транзакционной блокировки второй пользователь просто не сможет прочитать остаток, пока первый не завершит (или не отменит) свою операцию.

Причина 3: Упрощение программного кода

Посмотрим на пример кода, предоставленный в вопросе. В старой методике программисту пришлось бы вручную вычитать количество из документа из полученного остатка. Это лишние арифметические операции в коде 1С, которые при больших объемах данных замедляют работу.

В новой методике мы делегируем расчет платформе и СУБД. Нам не нужно знать, сколько будет. Нам нужно знать, что стало. Если КоличествоОстаток < 0, значит, мы попытались списать больше, чем было.

Пример запроса для контроля остатков после записи:


Запрос3 = Новый Запрос;
Запрос3.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос3.Текст = "ВЫБРАТЬ
                |    ОстаткиМатериаловОстатки.Материал,
                |    ОстаткиМатериаловОстатки.КоличествоОстаток
                |ИЗ
                |    РегистрНакопления.ОстаткиМатериалов.Остатки( , 
                |        Материал В (ВЫБРАТЬ НоменклатураДокумента.Номенклатура ИЗ НоменклатураДокумента)
                |        И Склад = &Склад) КАК ОстаткиМатериаловОстатки
                |ГДЕ
                |    ОстаткиМатериаловОстатки.КоличествоОстаток < 0";

Механизм транзакционного отката

Важно понимать: вызов метода Движения.Записать() не означает, что данные «намертво» впечатались в базу. Весь код процедуры ОбработкаПроведения выполняется внутри одной транзакции. Если в конце процедуры мы установим Отказ = Истина, платформа даст команду СУБД Rollback (Откат). Все записи, сделанные в регистр в ходе этой процедуры, будут физически удалены из таблиц базы данных так, будто их никогда и не было.

Когда все же нужно проверять «ДО»?

Несмотря на преимущества новой методики, существуют исключения. Рассмотрим ситуации, когда старый подход может быть оправдан:

  1. Сложное распределение по партиям: Если логика списания зависит от того, какие конкретно партии есть в наличии (например, FIFO с ручным подбором или сложная логика серий), нам необходимо сначала получить остатки в разрезе партий, чтобы понять, какие записи создавать в регистре.
  2. Высокий процент отказов: Если по специфике бизнеса 90% документов не проводятся из-за нехватки товара, постоянная запись и последующий откат транзакций могут создать избыточную нагрузку на лог транзакций СУБД.

Итоги

Подведем итог нашему анализу. Использование записи перед проверкой в ОбработкаПроведения — это не ошибка, а требование современной архитектуры 1С. Это позволяет:

Для успешной сдачи экзаменов «1С:Специалист» и разработки высоконагруженных систем крайне важно придерживаться именно новой методики проведения везде, где это позволяет бизнес-логика.

← На главную