Как исправить ошибку «Объект уже заблокирован» при вызове метода ЗаблокироватьДанныеДляРедактирования в 1С

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия IT и автоматизация бизнеса
← На главную

В процессе работы с типовыми и доработанными конфигурациями на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда при проведении документа или записи элемента справочника система выдает критическую ошибку: «Объект уже заблокирован». Особое коварство этой проблемы заключается в том, что она может возникать даже в тех случаях, когда документ не открыт у других пользователей, сеансы перезагружены, а сервер 1С был полностью перезапущен.

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

Суть проблемы и диагностика

Проанализируем техническую сторону ошибки. Обычно в стеке вызовов фигурирует метод ЗаблокироватьДанныеДляРедактирования(). Ошибка возникает из-за того, что платформа пытается установить пессимистическую блокировку на объект, который в рамках текущего сеанса или транзакции уже помечен как заблокированный.

Рассмотрим типовой фрагмент кода, на котором происходит сбой:


// Общий модуль: УправлениеСвойствами.Модуль
Процедура ЗаблокироватьОбъект(ВладелецСвойствОбъект) Экспорт
    // ... логика определения необходимости блокировки
    ЗаблокироватьДанныеДляРедактирования(ВладелецСвойствОбъект.Ссылка);
КонецПроцедуры

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

Способ 1. Использование расширения конфигурации (Рекомендуемый)

Если проблема вызвана особенностями работы типового механизма в конкретном релизе (например, 8.3.12), лучшим решением будет использование расширения. Это позволит избежать снятия конфигурации с поддержки и решит проблему «здесь и сейчас».

Разберем по шагам, как модифицировать код. Нам необходимо обернуть вызов метода блокировки в конструкцию Попытка ... Исключение или предварительно проверять состояние объекта. Однако, так как метод ЗаблокироватьДанныеДляРедактирования не имеет встроенного метода проверки «заблокировано ли уже мной», мы используем безопасный перехват:


&Вместо("ЗаблокироватьДанныеДляРедактирования")
Процедура Ист_ЗаблокироватьДанныеДляРедактирования(Ссылка, ИдентификаторФормы = Неопределено, ЗаблокированныйОбъект = Неопределено)
    Попытка
        ПродолжитьВызов(Ссылка, ИдентификаторФормы, ЗаблокированныйОбъект);
    Исключение
        // Если объект уже заблокирован в этом же сеансе, 
        // просто игнорируем ошибку и продолжаем работу.
        ЗаписьЖурналаРегистрации("БлокировкаДанных", УровеньЖурналаРегистрации.Предупреждение, , , 
            "Объект уже был заблокирован: " + Ссылка);
    КонецПопытки;
КонецПроцедуры

Такой подход позволяет программе проигнорировать повторную блокировку и успешно выполнить проведение документа.

Способ 2. Анализ транзакционных блокировок и замер производительности

Рассмотрим ситуацию, когда блокировка вызвана не ошибкой кода, а логикой взаимодействия объектов. Проанализируем ситуацию с помощью встроенного Замера производительности. Если в замере мы видим, что метод ЗаблокироватьДанныеДляРедактирования вызывается дважды для одной и той же ссылки в рамках одной цепочки вызовов, это свидетельствует о «двойной блокировке».

Для решения в этом случае можно попробовать принудительно освободить блокировку перед повторным вызовом (хотя это менее безопасно, чем первый способ):


РазблокироватьДанныеДляРедактирования(ВладелецСвойствОбъект.Ссылка);
ЗаблокироватьДанныеДляРедактирования(ВладелецСвойствОбъект.Ссылка);

Способ 3. Устранение инфраструктурных конфликтов

Иногда ошибка «Объект уже заблокирован» является следствием некорректной работы кластера серверов. Выясним, на что стоит обратить внимание системному администратору:

  1. Проверка портов и каталогов: Убедимся, что на сервере не запущено два экземпляра службы 1С, обращающихся к одной и той же базе данных через разные порты. Это может приводить к конфликту менеджеров блокировок.
  2. Сеансовые данные в SQL: При использовании MS SQL Server полезно проверить таблицу _SystemSettings. В редких случаях в ней могут «зависать» записи о блокировках, которые платформа интерпретирует как активные.
  3. Очистка серверного кэша: Полностью остановим службу 1C:Enterprise Server, перейдем в каталог srvinfo и удалим содержимое папок snccntx (данные сеансов) и reg_XXXX.

Дополнительные рекомендации

Проанализируем влияние Регламентных заданий. Если в момент проведения документа запускается фоновое задание, которое обращается к регистру сведений ЗначенияСвойствОбъектов (связанному с владельцем свойств), оно может удерживать исключительную блокировку. Попробуйте временно отключить регламентные задания и повторить операцию.

Важный момент: Если вы используете платформу версии 8.3.12 или ниже, рассмотрите возможность обновления на более стабильные релизы (8.3.18 и выше), так как в старых версиях механизмы управления блокировками в управляемых формах имели ряд задокументированных ошибок, связанных именно с методом ЗаблокироватьДанныеДляРедактирования.

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

← На главную