Прорыв блокировок на MS SQL через Управляемые — 24 июня 2026 г. в 05:07:45.330
Прорыв блокировок на MS SQL через Управляемые Недавно разбирали очень странную проблему… На MS SQL фиксировалось огромное количество таймаутов, при том что конфигурация на управляемых блокировках и по идее таймауты если могут быть, то должны фиксироваться на уровне 1С с событием TTIMEOUT, а не EXCP Пользователи сотни раз в час получали сообщение вида: Конфликт блокировок при выполнении транзакции Microsoft SQL Server Native Client: Превышено время ожидания запроса на блокировку При этом виновниками блокировок судя по анализу таймаутов на СУБД были совершенно безобидные запросы select… Но по мимо них и update, и insert, и delete, да ещё и на разных таблицах… Т.е. никакой системности, никакого одного подозреваемого и совершенно непонятное поведение СУБД. Как будто мы работаем на автоматических, а не на управляемых блокировках… Долго ломали голову с какой стороны подойти даже к анализу, не то что к решению проблемы, так как по ощущениям в системе не просто проблема, а «ушиб всей бабки»… Запрос: SELECT DB_NAME(tl.resource_database_id) AS database_name, tl.request_session_id, tl.request_mode AS lock_type,* FROM sys.dm_tran_locks tl WHERE DB_NAME(tl.resource_database_id) = 'erp' ORDER BY tl.request_session_id Показывал очень странный вывод – в колонке resource_type была только запись OBJECT, что означает что виновник блокировки блокирует всю таблицу, а не конкретную запись/записи в ней Если бы блокировались записи, то в колонке resource_type должна быть запись KEY. Получается, что мало того что мы каким-то чудесным образом прорываемся сквозь управляемые блокировки, ещё и блокируем каждый раз таблицы целиком… Но мы точно знаем – чудес не бывает! На соседней базе, на этом же сервер СУБД выполняем запрос, который начинает транзакцию на чтение, внутри становится на паузу в 1С минуту, чтобы мы успели увидеть, что и как он блокирует BEGIN TRANSACTION; SELECT * FROM dbo._InfoRg178 T1 WITH (HOLDLOCK) WHERE T1._Fld80 = 'test' WAITFOR DELAY '00:01:00'; COMMIT TRANSACTION; И видим что СУБД совершенно корректно блокирует по KEY, т.е. конкретную запись в таблице. Такой же запрос в проблемной базе, блокирует всю таблицу – OBJECT Значит разница именно в какой настройке в базе, а не в сервере СУБД. В итоге – нашли! А именно: https://its.1c.ru/db/metod8dev/content/5837/hdoc Важно! Начиная с версии платформы 8.3.22 необходимо выполнять дефрагментацию индексов по следующему алгоритму: До дефрагментации индекса необходимо включить страничные блокировки. Пример команды: ALTER INDEX index_name ON table_name SET (ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON); Выполнить дефрагментацию. Обратно выключить страничные блокировки. Пример команды: ALTER INDEX index_name ON table_name SET (ALLOW_PAGE_LOCKS = OFF, ALLOW_ROW_LOCKS = ON); При этом в плане обсуживания проблемной базы в самом последнем шаге устанавливается ALLOW_ROW_LOCKS = OFF Что отключает у MS SQL возможность использовать индексы и SQL Server будет вынужден использовать только табличные блокировки Причина проблемы именно в установленном параметре ALLOW_ROW_LOCKS = OFF для всех индексов всех таблиц базы. Вывод – читать документацию нужно очень внимательно, там всё написано верно, но так, что может и ввести в заблуждение))) И проверьте свои планы обслуживания баз на MS SQL

