Почему возникает конфликт блокировок при открытии документа и как его устранить?

Системный администратор 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

В процессе работы с тяжелыми конфигурациями (например, Управление производственным предприятием) пользователи иногда сталкиваются с ошибкой конфликта блокировок в момент открытия формы документа. При этом ошибка происходит сразу, еще до выполнения первого шага программного кода в процедурах типа ПередОткрытием или ПриСозданииНаСервере.

Разберем подробнее, почему возникает такая ситуация, как найти блокирующий процесс на стороне Microsoft SQL Server и какие действия необходимо предпринять для устранения проблемы.

Причины возникновения конфликта до выполнения кода 1С

Когда пользователь открывает форму документа, платформа 1С:Предприятие делает серии низкоуровневых фоновых запросов к СУБД. Это необходимо для считывания данных динамических списков, проверки прав доступа RLS (Record Level Security), а также выборки связанных реквизитов и сведений. Если в этот момент таблицы базы данных заблокированы другим процессом, платформа не может получить доступ к данным и выдает ошибку превышения времени ожидания блокировки.

Основными причинами таких блокировок являются:

  1. Незавершенное регламентное обслуживание СУБД: Если операции дефрагментации или реиндексации таблицы затянулись и вышли за рамки технологического окна, они удерживают монопольные блокировки на таблицы СУБД.
  2. Эскалация блокировок (Lock Escalation): При выполнении объемных сервис-процедур MS SQL Server автоматически укрупняет блокировки со строкового и страничного уровня до уровня всей таблицы (TAB).
  3. Режим изоляции и разделяемые блокировки: В автоматическом режиме блокировок чтение данных сопровождается установкой разделяемых блокировок (S-locks). Если параллельный процесс держит эксклюзивную блокировку (X-lock), операция чтения блокируется.

Диагностика блокирующего процесса в MS SQL Server

Выясним причину задержки. Если отладчик 1С не заходит в процедуры модуля формы и сразу выдает ошибку, необходимо обратиться к системным представлениям MS SQL Server. Чтобы оперативно найти сеанс, удерживающий блокировку, выполним следующий SQL-запрос:


SELECT DB_NAME(pr1.dbid) AS 'DB'
      ,pr1.spid AS 'ID жертвы'
      ,RTRIM(pr1.loginame) AS 'Login жертвы'
      ,pr2.spid AS 'ID виновника'
      ,RTRIM(pr2.loginame) AS 'Login виновника'
      ,pr1.program_name AS 'программа жертвы'
      ,pr2.program_name AS 'программа виновника'
      ,txt.[text] AS 'Запрос виновника'
FROM   MASTER.dbo.sysprocesses pr1(NOLOCK)
       JOIN MASTER.dbo.sysprocesses pr2(NOLOCK)
            ON  (pr2.spid = pr1.blocked)
       OUTER APPLY sys.[dm_exec_sql_text](pr2.[sql_handle]) AS txt
WHERE  pr1.blocked <> 0

Проанализируем результаты выполнения данного запроса. Колонка ID виновника показывает идентификатор процесса СУБД (SPID), который заблокировал ресурсы. Колонка Запрос виновника отобразит текст конкретной команды SQL, выполняемой блокирующим сеансом. Часто в качестве виновника выступает фоновая процедура обслуживания индексов (ALTER INDEX REBUILD) или сбора статистики.

Решения для устранения проблемы

После того как виновный процесс найден, рассмотрим варианты полного предотвращения подобных конфликтов блокировок.

  1. Корректировка технологического окна регламентов: Перенесите запуск процедур обслуживания СУБД на более раннее время или настройте жесткое ограничение по времени работы, чтобы к началу рабочего дня пользователей все регламентные операции были полностью завершены.
  2. Использование опции ONLINE при реиндексации: В редакциях MS SQL Server Enterprise и Developer пересборка индексов поддерживает параметр ONLINE = ON. Это позволяет перестраивать индексы параллельно с активным чтением и записью данных пользователями без захвата длительных монопольных блокировок.
  3. Интеллектуальное обслуживание индексов: Настройте сценарии обслуживания так, чтобы операция полной пересборки (REBUILD) выполнялась только при фрагментации выше 30%, а при меньшей фрагментации (от 5% до 30%) запускалась дефрагментация (REORGANIZE), которая не блокирует таблицы.
  4. Включение режима версионирования строк (RCSI): Настройка режима READ_COMMITTED_SNAPSHOT на уровне базы данных MS SQL Server позволяет читать данные из tempdb без установки разделяемых блокировок чтения, что исключает взаимные блокировки читающих пользователей и фоновых сервисных процессов.
← На главную