Почему 1С завершает работу при блокировке объекта и как это исправить

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием
← На главную

В процессе многопользовательской работы в 1С:ERP Управление предприятием 2 часто возникает ситуация, когда два сотрудника одновременно пытаются редактировать или проводить один и тот же документ. Вместо стандартного предупреждения система может выдать критическую ошибку или предложить «Завершить работу», что пользователи воспринимают как «вылет» из программы. Проанализируем причины этого поведения и разберем по шагам, как настроить систему так, чтобы работа не прерывалась аварийно.

Причина 1: Изменение логики платформы 8.3

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

Причина 2: Оптимистическая блокировка по умолчанию

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

Решение 1: Использование пессимистической блокировки

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

Рассмотрим пример кода, который можно разместить в модуле формы документа или реализовать через расширение в процедуре ПриЧтенииНаСервере или ПриОткрытии:


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

Решение 2: Обработка исключений в транзакции

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

Для реализации в расширении для процедуры ПередЗаписью на стороне сервера можно использовать следующий подход:


&НаСервере
Процедура Расш_ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    Попытка
        // Пытаемся заблокировать объект перед началом транзакции записи
        ТекущийОбъект.Заблокировать();
    Исключение
        Отказ = Истина;
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Не удалось записать документ, так как он заблокирован другим пользователем или процессом.";
        Сообщение.Сообщить();
    КонецПопытки;
КонецПроцедуры

Этот метод позволяет «мягко» прервать процесс записи, не доводя дело до аварийного завершения работы всей платформы.

Решение 3: Конфликты с фоновыми заданиями и дедлоки

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

В случае дедлока SQL-сервер выбирает одну из транзакций в качестве «жертвы» и откатывает её. Платформа 1С при получении сигнала об откате транзакции по причине дедлока может инициировать перезапуск сеанса. Чтобы минимизировать такие случаи, выполним следующие настройки:

  1. Увеличение времени ожидания блокировки: В консоли администрирования кластера серверов 1С можно увеличить параметр «Время ожидания блокировки данных». По умолчанию он составляет 20 секунд. Увеличение до 40-60 секунд даст системе больше времени на завершение параллельных процессов.
  2. Анализ технологического журнала: Для точного определения причины «вылета» настроим сбор логов ТЖ. Нас интересуют события EXCP (исключения) и TDEADLOCK. Это позволит увидеть, на какой именно таблице происходит конфликт.
  3. Разнесение процессов во времени: Если «вылеты» происходят при массовом проведении документов, рекомендуется настроить регламентные задания так, чтобы они не пересекались с периодами активной работы пользователей.

Решение 4: Проверка режима совместимости и обновление платформы

Проанализируем техническую составляющую. Существуют конкретные релизы платформы (например, в ветке 8.3.16 и 8.3.18), в которых была обнаружена ошибка: при возникновении конфликта управляемых блокировок клиентское приложение аварийно завершалось с дампом памяти.

Рекомендация: Убедитесь, что версия вашей платформы актуальна. Для ERP 2.4 рекомендуется использовать стабильные сборки 8.3.22 или выше. Обновление платформы часто само по себе устраняет проблему «вылетов», заменяя их штатным сообщением об ошибке Объект заблокирован.

Итоги

Мы рассмотрели, что проблема аварийного завершения сеанса в 1С при блокировках объектов обычно вызвана либо изменениями в поведении современных версий платформы, либо отсутствием обработки исключений в коде. Для устранения проблемы рекомендуется:

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

← На главную