Ошибки, связанные с конфликтами блокировок в многопользовательских системах 1С, являются одной из самых сложных и критичных проблем для производительности предприятия. В данной статье мы проанализируем ситуацию, когда пользователи сталкиваются с сообщением «Конфликт блокировок при выполнении транзакции», и разберем по шагам, как локализовать и устранить эту проблему.
Для начала разберем, почему возникают блокировки. В системе 1С:Предприятие существует два основных механизма управления блокировками: автоматический и управляемый. В автоматическом режиме за согласованность данных отвечает СУБД (MS SQL Server, PostgreSQL и др.), что часто приводит к избыточным блокировкам целых таблиц. В управляемом режиме программист сам указывает, какие именно данные (строки таблиц) нужно заблокировать.
Рассмотрим подробнее типичные сценарии, приводящие к конфликту:
Одним из самых эффективных способов решения проблемы является перевод конфигурации (или конкретных объектов) в режим управляемых блокировок. Проанализируем, как это сделать программно. В свойствах конфигурации необходимо установить параметр РежимУправленияБлокировкойДанных в значение Управляемый.
После этого мы должны самостоятельно описывать блокировки в коде перед выполнением запросов, которые читают данные для последующего изменения. Разберем на примере:
ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиТоваров");
ЭлементБлокировки.УстановитьЗначение("Склад", СкладСсылка);
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
Блокировка.Заблокировать();
Этот код позволяет заблокировать только остатки по конкретному складу, не мешая другим пользователям работать с этим же регистром по другим складам. Это критически важно для высоконагруженных систем.
Посмотрим на пример того, как неправильное чтение данных может вызвать проблему. Часто разработчики используют запрос внутри цикла или читают данные, которые им не нужны для текущей операции. Мы рекомендуем следовать правилу: «Блокируй как можно позже, отпускай как можно раньше».
Проанализируем шаги по оптимизации кода:
Записать()).МенеджерВременныхТаблиц для подготовки данных, чтобы основной запрос к реальным таблицам БД выполнялся максимально быстро.ГДЕ и СВЯЗИ.Рассмотрим пример правильной подготовки данных перед записью:
// Сначала готовим данные во временной таблице
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.Текст = "ВЫБРАТЬ * ПОМЕСТИТЬ ВТ_Данные ИЗ &ТаблицаЗначений КАК ТЗ";
Запрос.УстановитьПараметр("ТаблицаЗначений", ТЗ_Списания);
Запрос.Выполнить();
// Начинаем транзакцию только перед записью
НачатьТранзакцию();
Попытка
// Устанавливаем управляемую блокировку
Блокировка = Новый БлокировкаДанных;
// ... описание блокировки ...
Блокировка.Заблокировать();
// Выполняем запись
Объект.Записать();
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
Если ошибка сохраняется, нам необходимо выяснить, какой именно процесс держит блокировку. Для этого воспользуемся инструментами платформы и СУБД. В консоли кластера серверов 1С можно увидеть активные сеансы и блокировки, которые они удерживают.
Разберем алгоритм поиска:
Также полезно использовать технологический журнал (ТЖ). Настроим сбор событий TLOCK, чтобы увидеть подробности: имя таблицы, тип блокировки и контекст кода (стек вызова), который ее вызвал. Это позволит нам точно определить место в коде, требующее оптимизации.
Иногда причина конфликта кроется не в коде 1С, а в том, как СУБД интерпретирует запрос. Если поле не индексировано, SQL Server может применить Lock Escalation (укрупнение блокировки) до уровня страницы или всей таблицы.
Посмотрим на рекомендации по индексам:
Важный момент: в 1С 8.3 при использовании управляемых блокировок система сама старается минимизировать уровень блокировок в СУБД до Read Committed, что значительно снижает вероятность конфликтов по сравнению с автоматическим режимом (где используется Repeatable Read или Serializable).
Мы проанализировали основные причины возникновения ошибок «Конфликт блокировок» и рассмотрели способы их решения. Подведем итоги нашей совместной работы:
Соблюдение этих правил позволит вашей системе работать стабильно даже при большом количестве одновременно работающих пользователей. Помните, что оптимизация блокировок — это итерационный процесс, требующий регулярного мониторинга производительности.