При параллельной работе пользователей и регламентных заданий в 1С нередко возникает ситуация, когда обычное чтение данных из регистров накопления приводит к блокировке записи. Пользователи при проведении документов получают ошибки ожидания блокировки или сталкиваются с сильными задержками, хотя в запросе регламентного задания данные только считываются и флаг Блокировать для изменения не установлен. Разберем детально, почему это происходит и как устранить конфликты блокировок.
Проанализируем техническую сторону взаимодействия платформы 1С и СУБД. Поведение блокировок зависит от установленного режима управления блокировками данных и структуры самих запросов:
REPEATABLE READ или SERIALIZABLE. При чтении данных внутри транзакции накладываются разделяемые блокировки (S-блокировки). Они удерживаются до самого окончания транзакции. В это же время проведение документов требует установки монопольных блокировок (X-блокировок) на те же диапазоны данных, что приводит к взаимным блокировкам и таймаутам.Остатки физически обращается к таблице итогов и таблице движений регистра (для досчета движений от точки рассчитанных итогов до переданного момента времени). Если граница итогов не сдвинута на актуальную дату, запрос сканирует широкий диапазон записей в таблице движений, удерживая разделяемые блокировки на всех затронутых строках.Рассмотрим первоочередные меры, которые позволяют снизить нагрузку и исключить блокировку таблиц без кардинальной переработки конфигурации:
НачатьТранзакцию() ... ЗафиксироватьТранзакцию()). Чтение вне транзакции позволяет СУБД снимать блокировки чтения сразу в момент завершения выборки строк, а не удерживать их до завершения всего фонового процесса.ГДЕ. Это позволит СУБД использовать кластерные индексы таблицы итогов и не сканировать лишние строки.Если виртуальная таблица остатков обращается к неактуальным итогам, СУБД вынуждена накладывать блокировки на таблицу движений. Настроим регламентный пересчет итогов:
РегистрыНакопления.УстановитьПериодРассчитанныхИтогов().Наиболее эффективным решением проблемы параллельности чтения и записи является использование управляемого режима блокировок платформы 1С:
READ COMMITTED SNAPSHOT (версионирование строк). При таком подходе операции чтения никогда не блокируют операции записи, а запись не блокирует чтение.БлокировкаДанных, чтобы гарантировать корректность контроля остатков при параллельной записи.Посмотрим на пример установки управляемой блокировки в модуле проведения документа:
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ТоварыНаСкладах");
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
ЭлементБлокировки.УстановитьЗначение("Склад", Склад);
ЭлементБлокировки.ИсточникДанных = ТаблицаТоваров;
ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");
Блокировка.Заблокировать();
Таким образом, сочетание оптимизации запросов, регулярного смещения границы рассчитанных итогов и перехода на управляемый режим позволяет полностью исключить взаимоблокировки регламентных заданий и проводящихся документов.