Гайд 1С: Оптимизация проведения документов задним числом с контролем остатков
Массовое перепроведение документов или закрытие месяца сопровождается следующими проблемами:
- Взаимные блокировки (Deadlocks) транзакций в СУБД с ошибкой
Конфликт блокировок при выполнении транзакции. - Катастрофическое падение скорости перепроведения с сотен документов в секунду до единиц.
- Эскалация блокировок до уровня всей таблицы итогов регистров накопления.
- Ошибки ложного контроля остатков из-за некорректного чтения срезов итогов на момент документа.
1. Использование методики проведения «по новой схеме» (Управляемый режим)
Классическая схема с предварительным чтением остатков блокирует диапазон данных до формирования движений. Новая схема сначала записывает движения документа, а затем проверяет остатки единым запросом:
- Очистить старые движения документа без фиксации пустых наборов.
- Установить управляемую блокировку (
БлокировкаДанных) только по позициям номенклатуры и складам документа в режимеРежимБлокировкиДанных.Исключительный. - Записать новые движения документа с признаком
Записывать = Истина. - Выполнить запрос к таблице остатков регистра с фильтром по отрицательным значениям остатка (
КоличествоОстаток < 0). - Если обнаружены минусы — вызвать исключение и откатить транзакцию.
// Установка точечной управляемой блокировки
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ТоварыНаСкладах");
ЭлементБлокировки.УстановитьЗначение("Склад", ДокументОбъект.Склад);
ЭлементБлокировки.ИсточникДанных = ДокументОбъект.Товары;
ЭлементБлокировки.ИспользоватьПоляЗаписи("Номенклатура", "Номенклатура");
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
Блокировка.Заблокировать();2. Включение разделения итогов регистров
В свойствах регистров накопления включите Разрешить разделение итогов. Это устраняет блокировку одной строки итогов разными параллельными фоновыми потоками за счет добавления скрытого разделителя с последующим агрегированием регламентным заданием СлияниеСлужебныхИтогов.
3. Оптимизация смещения границы итогов
При постоянной работе задним числом регулярно сдвигайте период рассчитанных итогов регистров (УстановитьПериодРассчитанныхИтогов) на дату окончания закрываемого месяца, чтобы запросы к виртуальным остаткам не выполняли обход всех записей журнала с начала времен.
Частые вопросы (FAQ)
Почему запись движений перед проверкой остатков эффективнее предварительного чтения?
Запись движений сразу накладывает строгую блокировку на уровне строк СУБД. Проверка отрицательных остатков одним запросом исключает повторное чтение и удерживает блокировку минимальное время.
Как влияет разделение итогов на скорость формирования отчетов?
Разделение итогов ускоряет параллельную запись, но может незначительно замедлить чтение отчетов, так как СУБД суммирует строки по нескольким разделителям. Регламентное слияние итогов устраняет этот оверхед.
Что делать, если дедлоки происходят из-за разного порядка блокировки строк табличной части?
Перед установкой блокировки и записью движений обязательно сортируйте табличную часть документа по возрастанию ключевых полей (Номенклатура, Характеристика, Склад). Единый порядок захвата ресурсов исключает классический взаимный дедлок (Deadlock).
Нужно ли отключать автоматический пересчет итогов при массовой загрузке документов?
Да, при пакетной загрузке исторических данных отключите итоги через РегистрыНакопления.ИмяРегистра.УстановитьИспользованиеИтогов(Ложь), запишите документы, а затем включите итоги и выполните единый пересчет.