В процессе работы с тяжелыми конфигурациями (например, Управление производственным предприятием) пользователи иногда сталкиваются с ошибкой конфликта блокировок в момент открытия формы документа. При этом ошибка происходит сразу, еще до выполнения первого шага программного кода в процедурах типа ПередОткрытием или ПриСозданииНаСервере.
Разберем подробнее, почему возникает такая ситуация, как найти блокирующий процесс на стороне Microsoft SQL Server и какие действия необходимо предпринять для устранения проблемы.
Когда пользователь открывает форму документа, платформа 1С:Предприятие делает серии низкоуровневых фоновых запросов к СУБД. Это необходимо для считывания данных динамических списков, проверки прав доступа RLS (Record Level Security), а также выборки связанных реквизитов и сведений. Если в этот момент таблицы базы данных заблокированы другим процессом, платформа не может получить доступ к данным и выдает ошибку превышения времени ожидания блокировки.
Основными причинами таких блокировок являются:
TAB).S-locks). Если параллельный процесс держит эксклюзивную блокировку (X-lock), операция чтения блокируется.Выясним причину задержки. Если отладчик 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) или сбора статистики.
После того как виновный процесс найден, рассмотрим варианты полного предотвращения подобных конфликтов блокировок.
ONLINE = ON. Это позволяет перестраивать индексы параллельно с активным чтением и записью данных пользователями без захвата длительных монопольных блокировок.REBUILD) выполнялась только при фрагментации выше 30%, а при меньшей фрагментации (от 5% до 30%) запускалась дефрагментация (REORGANIZE), которая не блокирует таблицы.READ_COMMITTED_SNAPSHOT на уровне базы данных MS SQL Server позволяет читать данные из tempdb без установки разделяемых блокировок чтения, что исключает взаимные блокировки читающих пользователей и фоновых сервисных процессов.