Почему при выполнении транзакции возникает ошибка «Объект заблокирован» в 1С 7.7 на MS SQL?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При переходе с файловой версии базы данных на клиент-серверный вариант (MS SQL) разработчики часто сталкиваются со специфической ошибкой: При выполнении транзакции произошла ошибка! Объект заблокирован. Эта ситуация особенно болезненна, если база самописная и активно использует создание новых элементов справочников прямо из форм выбора или подбора. Давайте разберем, почему это происходит и как исправить поведение системы.

Анализ причин блокировки при создании объектов

В файловой версии 1С 7.7 управление блокировками лежит на самой платформе, которая работает с файлами БД. В SQL-версии ситуация иная: за блокировки отвечает непосредственно MS SQL Server. Когда вы открываете форму выбора справочника и пытаетесь из неё создать новый элемент, происходит цепочка событий:

  1. Открывается форма документа, удерживающая контекст транзакции.
  2. Вы вызываете форму подбора (например, через ОткрытьФорму).
  3. Платформа пытается зафиксировать выбор нового объекта, но SQL-сервер видит конфликт транзакций, так как форма документа еще не завершила свою работу.
  4. Возникает взаимная блокировка (deadlock), и система выбрасывает ошибку.

Методы решения проблемы

Разберем способы, которые помогут избежать появления этой ошибки в коде вашей конфигурации.

1. Отказ от интерактивного создания в форме выбора

Самый надежный способ — исключить возможность создания новых элементов справочника непосредственно в форме, которая была открыта для выбора значения. Интерактивное создание объектов «на лету» в форме подбора — это частая причина нестабильности на SQL.

Рекомендация: Сделайте создание нового элемента отдельным процессом. Например, добавьте кнопку «Создать» на форму документа, которая будет открывать карточку справочника в отдельном окне. После записи элемента пользователем, используйте механизм оповещения для обновления данных в документе.

2. Использование механизма Оповестить()

Если вам все же необходимо открывать форму для создания, используйте штатный механизм обмена данными между формами. Вместо того чтобы пытаться записать ссылку напрямую в реквизит формы документа, примените оповещения.

В форме создания элемента после успешной записи вызовите метод:


// В модуле формы элемента справочника
Оповестить("ОбъектСоздан", НовыйОбъектСсылка, "ИдентификаторКонтекста");

А в основной форме документа обработайте это событие:


Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
    Если ИмяСобытия = "ОбъектСоздан" Тогда
        // Присваиваем значение реквизиту
        РеквизитДоговора = Параметр;
    КонецЕсли;
КонецПроцедуры

3. Оптимизация кода вызова формы

Проанализируем текущий подход к вызову формы выбора в коде. Часто разработчики используют ОткрытьФорму с передачей параметров. Убедитесь, что вы не вызываете блокирующие функции внутри ПриОткрытии самой формы списка.

Разберем пример кода, который часто встречается в конфигурациях:


Процедура ПриНачалеВыбораЗначения(ИД, Флаг)
    Если ИД = "ПараметрыДляФормированияПлатежныхДокументов" Тогда
        Флаг = 0; // Отменяем стандартный выбор
        СЗ = СоздатьОбъект("СписокЗначений");
        // ... установка параметров отбора ...
        ОткрытьФорму("Справочник.ПараметрыДляФормированияПлатежныхДокументов#" + Контрагент, СЗ);
    КонецЕсли;
КонецПроцедуры

Если в ПриОткрытии вызываемой формы есть сложная логика, выполняющая запросы к БД, она должна быть максимально оптимизирована. Помните: лишние транзакции внутри ПриОткрытии в среде SQL-сервера крайне нежелательны.

4. Проверка уровня изоляции транзакций SQL

Если ошибка возникает даже при одиночной работе, обратитесь к настройкам MS SQL Server. Для корректной работы 1С 7.7 уровень изоляции должен быть Read Committed. Если уровень выше (например, Serializable), сервер будет блокировать ресурсы даже для чтения данных, которые были изменены, но не зафиксированы, что и приводит к ошибке Объект заблокирован.

Подведем итог: если вы столкнулись с этой ошибкой, в первую очередь попробуйте:

Помните, что архитектурные решения, заложенные в конфигурацию, должны учитывать транзакционную модель SQL-сервера. Разделение процессов выбора и создания — это не просто хороший тон программирования, это залог стабильности вашей системы.

← На главную