Часто у разработчиков, начинающих глубоко изучать механизмы платформы 1С:Предприятие, возникает закономерный вопрос: почему фирма «1С» в своих современных типовых конфигурациях (таких как ERP, Комплексная автоматизация, Управление торговлей) массово отказалась от автоматического свойства Записывать модифицированные? Почему предпочтение всегда отдается режиму Записывать выбранные, при котором мы вынуждены вручную управлять флагами записи? Давайте подробно разберем этот механизм, проанализируем исторический контекст и выясним технические причины такого решения.
Для начала рассмотрим подробнее, как именно функционируют оба этих режима внутри транзакции проведения документа.
Режим «Записывать выбранные» (стандартный и рекомендуемый)
В этом режиме платформа не делает никаких предположений о том, что именно нужно сохранить в базу данных. После завершения процедуры ОбработкаПроведения система анализирует коллекцию движений документа. Она записывает в базу данных только те наборы записей регистров, для которых программист явно установил свойство Записывать в значение Истина.
Посмотрим на пример классического кода:
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
// Явно указываем платформе, что этот регистр нужно записать
Движения.ОстаткиТоваров.Записывать = Истина;
Для Каждого СтрокаТЧ Из Товары Цикл
Движение = Движения.ОстаткиТоваров.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
Движение.Период = Дата;
Движение.Номенклатура = СтрокаТЧ.Номенклатура;
Движение.Количество = СтрокаТЧ.Количество;
КонецЦикла;
КонецПроцедуры
Платформе абсолютно неважно, добавили вы строки в набор или нет. Если флаг Записывать = Истина установлен, система выполнит операцию записи (например, просто очистит старые движения, если новых строк добавлено не было).
Режим «Записывать модифицированные» (устаревший)
При использовании этого режима в конце транзакции проведения платформа самостоятельно обходит коллекцию движений документа. Она проверяет системное свойство набора записей — Модифицированность. Если набор был изменен в оперативной памяти (в него добавили записи, очистили или загрузили таблицу), платформа видит, что Модифицированность = Истина, автоматически устанавливает маркер записи и сохраняет изменения в СУБД.
Многие разработчики удивляются: если пользователь перепроводит измененный документ, почему на старте процедуры проведения у всех движений флаг модифицированности стоит в значении Ложь?
Разберем по шагам. Дело в том, что свойство Модифицированность не имеет никакого отношения к тому, изменил ли пользователь реквизиты документа в форме. Это свойство относится исключительно к объекту НаборЗаписей, который находится в оперативной памяти сервера во время выполнения кода.
В момент старта процедуры ОбработкаПроведения коллекции наборов записей пусты или еще не прочитаны из базы. С точки зрения оперативной памяти они «нетронуты». Как только в коде отрабатывает любой метод, физически меняющий данные регистра в памяти (например, Добавить(), Очистить() или Загрузить()), свойство Модифицированность для этого конкретного набора моментально меняется на Истина.
Чтобы понять отказ от старого механизма, проанализируем ситуацию в ретроспективе. Режим Записывать модифицированные массово применялся в старых конфигурациях на обычных формах (например, в «Управление торговлей 10.3» или «УПП»). В то время архитектура проведения была другой: документы сначала долго собирали данные, формировали виртуальные таблицы, проверяли остатки в оперативной памяти и только в самом конце неявно сбрасывали все сформированные наборы в базу.
Сегодня этот механизм признан устаревшим (legacy). В официальной документации прямо указывается, что он оставлен в платформе исключительно для обратной совместимости при конвертации старых баз. Для всех новых разрабатываемых объектов по умолчанию всегда устанавливается режим Записывать выбранные.
Одной из ключевых причин тотального перехода на явный контроль стала «новая методика проведения». Современные системы требуют высокой производительности и минимизации блокировок.
В конфигурациях нового поколения (ERP, УТ 11, КА) контроль отрицательных остатков работает принципиально иначе:
Посмотрим на пример реализации такого подхода:
Движения.ОстаткиТоваров.Записывать = Истина;
// Формируем движения...
// Явно записываем движения ДО конца обработки проведения
Движения.Записать();
// Выполняем запрос к СУБД для контроля отрицательных остатков
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОстаткиТоваровОстатки.Номенклатура
|ИЗ
| РегистрНакопления.ОстаткиТоваров.Остатки(
| &ГраницаКонтроля,
| Номенклатура В (&СписокНоменклатурыДокумента)
| ) КАК ОстаткиТоваровОстатки
|ГДЕ
| ОстаткиТоваровОстатки.КоличествоОстаток < 0";
Результат = Запрос.Выполнить();
Если Не Результат.Пустой() Тогда
Отказ = Истина; // Обнаружен дефицит
КонецЕсли;
Очевидно, что автоматическая запись «в самом конце», как это делает Записывать модифицированные, для такой архитектуры физически не подходит. Разработчику нужен жесткий, предсказуемый контроль над тем, в какой именно момент времени набор записей улетит в СУБД.
Вторая, не менее важная причина — борьба со взаимными блокировками на уровне СУБД при высоконагруженной параллельной работе пользователей.
Представим, что два пользователя одновременно проводят разные документы, которые двигают одни и те же регистры. В реляционных базах данных критически важно, чтобы запись в таблицы всегда происходила в одинаковом, строго заданном порядке (например, сначала Регистр А, затем Регистр Б). Если первый документ запишет сначала А, а потом Б, а второй — сначала Б, а потом А, произойдет Deadlock (взаимоблокировка).
В режиме Записывать модифицированные наборы записей отправляются в СУБД своеобразным «пакетом» в конце транзакции. Неявный и слабо контролируемый порядок их фиксации часто приводил к трудноуловимым конфликтам блокировок. Когда программист использует Записывать выбранные и вызывает метод Движения.Записать() вручную, он строго регламентирует порядок записи таблиц базы данных, обеспечивая стабильность системы.
В сообществе разработчиков 1С ходит миф о том, что опция «Записывать модифицированные» записывает не только изменившиеся ресурсы, но и все остальные, что якобы перегружает базу, а «Выбранные движения» позволяют выбирать конкретные ресурсы для записи. Это технически некорректное утверждение.
Давайте проясним этот момент. Платформа 1С:Предприятие при записи движений документа всегда пишет строки (объекты НаборЗаписей) целиком. Сохраняется вся строка: все измерения, ресурсы и реквизиты, независимо от того, какой режим вы выбрали в конфигураторе. Никакого «выборочного сохранения отдельных колонок регистра» в платформе не существует в принципе. Проблема устаревшего режима заключается исключительно в непредсказуемости логики кода и моменте записи, а не в структуре сохраняемых данных.
Проанализируем всё вышесказанное и сделаем выводы. Механизм Записывать выбранные — это осознанный выбор вендора в пользу предсказуемости, масштабируемости и производительности системы.
Используя этот подход, мы получаем:
Именно поэтому встретить режим «Записывать модифицированные» в современных конфигурациях почти невозможно, и при разработке собственных решений всегда следует отдавать предпочтение явному управлению через коллекцию Движения.