При активной многопользовательской работе в 1С пользователи нередко сталкиваются с ошибками ожидания блокировок при записи или проведении документов. В консоли кластера серверов 1С при этом можно заметить, что сеанс одного из пользователей длительное время удерживает соединение, а показатель «Захвачено СУБД» непрерывно растет. Разберем подробно, что означают эти показатели, почему возникают блокировки и какими способами можно локализовать и устранить проблему.
Показатель «Захвачено СУБД» (или время захвата СУБД) отображает суммарное время в секундах или миллисекундах, в течение которого сеанс удерживал ресурсы базы данных в рамках текущего контекста или открытых соединений. Сам по себе этот показатель отражает интенсивность работы пользователя с базой данных, однако его аномальный или бесконтрольный рост сигнализирует о следующих проблемах:
Одной из скрытых причин постоянного роста показателя «Захвачено СУБД» в течение рабочего дня является некорректная работа с временными таблицами в циклических или часто вызываемых процедурах. Если объект МенеджерВременныхТаблиц создается в контексте выполнения, наполняется данными, но не закрывается при выходе, временные таблицы могут продолжать удерживать физические ресурсы во временной базе (например, tempdb в MS SQL Server).
Рассмотрим пример кода, в котором выполняется явное освобождение ресурсов с помощью метода Закрыть():
Процедура ОбработатьДанныеРабочихМест()
МВТРабочиеМеста = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МВТРабочиеМеста;
Запрос.Текст =
"ВЫБРАТЬ
| Ссылка КАК РабочееМесто
|ПОМЕСТИТЬ ВТ_РабочиеМеста
|ИЗ
| Справочник.РабочиеМеста КАК Спр";
Запрос.Выполнить();
// Выполнение основных расчетов и логики обработки данных
// ...
// Обязательное освобождение ресурсов менеджера
Если МВТРабочиеМеста <> Неопределено Тогда
МВТРабочиеМеста.Закрыть();
КонецЕсли;
КонецПроцедуры
Явный вызов метода Закрыть() удаляет созданные временные таблицы из СУБД и снимает избыточную нагрузку на соединения сеанса.
Проанализируем распространенную ошибку, когда внутри открытой транзакции вызываются интерфейсные окна или паузы. Если пользователь отходит от рабочего места с открытым окном предупреждения или вопроса, транзакция остается активной, удерживая эксклюзивные блокировки на таблицы.
Вопрос(), Предупреждение(), ОткрытьФормуМодально() внутри блока НачатьТранзакцию() ... ЗафиксироватьТранзакцию() или в обработчиках ОбработкаПроведения().Для высоконагруженных баз с большим числом одновременных пользователей автоматический режим управления блокировками приводит к частым конфликтам. Разберем системные настройки платформы и СУБД:
БлокировкаДанных, который блокирует только необходимые комбинации измерений, а не всю таблицу регистра целиком.READ_COMMITTED_SNAPSHOT (RCSI). Это исключает конфликты между операциями чтения (отчеты) и записи (проведение документов).Max Degree of Parallelism (MAXDOP) значением 1, чтобы исключить взаимные блокировки параллельных потоков внутри одного сложного запроса.Для оперативного выявления «виновника» блокировки применим комплексный подход:
TLOCK (установка блокировок и ожидания), TTIMEOUT (превышение таймаута ожидания блокировки) и TDEADLOCK (взаимоблокировки) для получения точного контекста модуля 1С, где возник конфликт.sp_who2 или динамические представления sys.dm_tran_locks и sys.dm_exec_requests для обнаружения блокирующего потока (Blocking SPID).