Работа с крупными информационными базами «1С:Управление производственным предприятием» (УПП) объемом более 500–800 Гб накладывает особые требования к выполнению регламентных операций. Одной из самых ресурсоемких задач является Расчет себестоимости выпуска (РСВ). Часто системные администраторы и программисты сталкиваются с ситуацией, когда даже запуск РСВ в режиме «вне транзакции» не спасает от конфликтов блокировок, мешая оперативной работе пользователей. Разберем подробно, почему это происходит и какие шаги необходимо предпринять для решения проблемы.
Для начала проанализируем, что на самом деле делает флаг «Выполнять расчет вне транзакции» в документе РегламентнаяОперация. Многие ошибочно полагают, что этот режим полностью отключает механизм блокирования данных. Однако это не так. В обычном режиме РСВ пытается выполнить все расчеты и записи в рамках одной гигантской транзакции. Если расчет длится 5 часов, то все это время данные будут заблокированы.
В режиме «вне транзакции» система разбивает процесс на множество мелких этапов. Однако запись каждого конкретного набора записей в регистры (например, в РегистрБухгалтерии) все равно происходит внутри транзакции. Вызов метода Записать() объекта РегистрБухгалтерииНаборЗаписей инициирует транзакцию на уровне СУБД. Если набор записей содержит тысячи строк, блокировка становится ощутимой для других сеансов.
Рассмотрим ситуацию: расчет себестоимости идет за январь, а пользователь пытается провести производственный документ за февраль. Казалось бы, периоды разные, и конфликта быть не должно. Однако на больших базах УПП блокировка все равно возникает по следующим причинам:
TABLOCK). В этот момент любое обращение к РегиструБухгалтерии, даже по другому периоду, будет ждать завершения расчета.Serializable. Это заставляет СУБД блокировать не только существующие записи, но и диапазоны индексов, чтобы предотвратить появление «фантомных» записей. Если физически данные за разные месяцы расположены на соседних страницах индекса, они будут заблокированы совместно.Рассмотрим один из самых эффективных архитектурных способов — создание узла Распределенной Информационной Базы (РИБ). Это позволяет полностью изолировать процесс расчета от оперативной работы пользователей.
Посмотрим на алгоритм действий:
Если вариант с РИБ слишком сложен, проанализируем технические настройки сервера. Для снижения вероятности конфликтов при выполнении РегистрБухгалтерииНаборЗаписей.Записать() выполним следующие шаги:
Настройка MAXDOP. Установим параметр Max Degree of Parallelism в значение 1 на уровне SQL Server. Это предотвратит ситуацию, когда одна тяжелая транзакция записи РСВ захватывает все ядра процессора и вызывает взаимоблокировки (Deadlocks) при параллельном чтении данных другими пользователями.
Обслуживание индексов. Перед расчетом себестоимости крайне важно выполнить дефрагментацию или перестроение индексов по регистру бухгалтерии и регистру накопления «Затраты». Высокая фрагментация заставляет SQL Server чаще прибегать к сканированию всей таблицы вместо поиска по индексу, что мгновенно ведет к эскалации блокировок.
Рассмотрим пример кода, который может быть полезен при программном управлении блокировками, если вы решитесь на доработку модуля ПроцедурыРасчетаСебестоимостиВыпуска:
// Пример установки управляемой блокировки перед записью набора (если режим базы позволяет)
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрБухгалтерии.Хозрасчетный");
ЭлементБлокировки.УстановитьЗначение("Период", Новый Диапазон(ДатаНачала, ДатаОкончания));
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
Блокировка.Заблокировать();
Проанализируем возможность сокращения объема данных, обрабатываемых за один раз. В УПП расчет себестоимости можно запускать по отдельным этапам. Вместо одного общего запуска, разберем по шагам выполнение регламентных операций:
Выполняя эти этапы последовательно с небольшими паузами, мы даем возможность SQL Server «отпустить» блокировки и обработать очередь запросов от производственных документов пользователей. Также рекомендуется перенести выполнение наиболее тяжелых этапов на ночное время, используя планировщик задач.
Блокировки при расчете себестоимости в УПП на базе 800 Гб — это не ошибка программы, а следствие естественных ограничений СУБД при работе с огромными массивами данных в автоматическом режиме блокировок. Для стабильной работы рекомендуем сочетать регулярное обслуживание индексов SQL, настройку MAXDOP и, при необходимости, вынос расчета в отдельный узел РИБ. Это позволит сохранить высокую производительность системы даже при интенсивной работе пользователей в будущих периодах.