Почему не работает Заблокировать() в Попытка...Исключение в 1С и как это исправить

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

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

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

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


Если Не ЭтоНовый() Тогда
    Попытка
        ЭтотОбъект.Заблокировать();
    Исключение
        Предупреждение("Документ открыт или заблокирован другим пользователем!");
    КонецПопытки;
КонецЕсли;

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

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

Причины возникновения невосстановимого исключения

Проанализируем ключевые причины, из-за которых конструкция Попытка ... Исключение пропускает ошибку блокировки:

  1. Платформенная ошибка релиза (баг платформы): В некоторых версиях платформы (например, в линейке 8.3.9, в частности 8.3.9.1850) обработка пессимистических блокировок на уровне сервиса кластера серверов DataEditLockService вызывает невосстановимое системное исключение. Платформа воспринимает сбой как фатальную ошибку ядра и мгновенно завершает клиентский процесс.
  2. Последствия динамического обновления конфигурации: Частое применение динамического обновления («горячее» обновление информационной базы) ведет к рассинхронизации кэша метаданных на сервере и клиенте. В результате зависают объектные блокировки, блокируется нормальный вход в Конфигуратор и нарушается логика работы методов Заблокировать() и Заблокирован().
  3. Особенности метода Заблокирован(): Метод Заблокирован() проверяет состояние блокировки только текущего экземпляра объекта в памяти, а не состояние записи в базе данных другими сеансами. Это важно учитывать при проектировании логики проверки.

Способы решения проблемы

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

Способ 1. Обновление платформы 1С:Предприятие

Самым эффективным и гарантированным способом устранения данной ошибки является обновление платформы 1С. Поскольку невосстановимое исключение вызывается платформенной ошибкой сервиса блокировок, переход на более свежий релиз полностью решает проблему. На практике подтверждено, что обновление с версии 8.3.9 на релизы линейки 8.3.10 (например, 8.3.10.2699 и выше) устраняет фатальный сбой, и блок Попытка ... Исключение снова начинает штатно перехватывать ошибки блокировки объектов.

Способ 2. Использование метода ЗаблокироватьДанныеДляРедактирования()

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

Посмотрим на пример применения в форме документа или информационной обработке:


Перем КлючБлокировки;

Попытка
    // Устанавливаем блокировку через глобальный контекст
    ЗаблокироватьДанныеДляРедактирования(СсылкаНаОбъект, КлючБлокировки, УникальныйИдентификатор);
Исключение
    Сообщить("Не удалось заблокировать объект: " + ОписаниеОшибки());
КонецПопытки;

Для снятия такой блокировки используется парный метод РазблокироватьДанныеДляРедактирования():

РазблокироватьДанныеДляРедактирования(СсылкаНаОбъект, УникальныйИдентификатор);

Способ 3. Очистка кэша и обслуживание информационной базы

Если ошибка проявилась внезапно после проведения динамического обновления, выполним комплекс профилактических и восстановительных работ:

  1. Очистка локального кэша 1С: Удалим каталоги временных файлов платформы у пользователей на рабочих станциях и сервере терминалов (папки в %LocalAppData%\1C\1cv8 и %AppData%\1C\1cv8).
  2. Перезапуск процессов кластера серверов: Перезапустим службу серверов 1С (процессы rphosts, rmngr) для сброса зависших сеансовых блокировок.
  3. Проведение тестирования и исправления: В режиме Конфигуратора выполним процедуру Тестирование и исправление информационной базы с обязательной переиндексацией таблиц и проверкой логической целостности.
  4. Отказ от динамических обновлений: Внесем изменения в регламент работы администраторов и разработчиков — любые обновления конфигурации базы данных следует проводить только с завершением сеансов пользователей без применения динамического обновления.
← На главную