В процессе многопользовательской работы в 1С:ERP Управление предприятием 2 часто возникает ситуация, когда два сотрудника одновременно пытаются редактировать или проводить один и тот же документ. Вместо стандартного предупреждения система может выдать критическую ошибку или предложить «Завершить работу», что пользователи воспринимают как «вылет» из программы. Проанализируем причины этого поведения и разберем по шагам, как настроить систему так, чтобы работа не прерывалась аварийно.
Разберем ситуацию, которая начала массово проявляться в релизах платформы, начиная с 8.3.15. В старых версиях 1С при возникновении конфликта блокировок пользователь видел обычное модальное окно с кнопкой «ОК». После нажатия работа продолжалась. В современных версиях политика платформы изменилась: при возникновении необработанного исключения, связанного с блокировкой данных в транзакции, система часто выводит диалог выбора: «Перезапустить» или «Завершить работу». С точки зрения пользователя это выглядит как закрытие программы.
В управляемых формах 1С по умолчанию используется оптимистическая блокировка. Проанализируем, как она работает: система позволяет открыть документ любому количеству пользователей. Проверка на то, изменил ли кто-то данные, происходит только в момент нажатия кнопки Записать или Провести. Если второй пользователь нажимает «Записать» чуть позже первого, возникает конфликт версий. Если этот конфликт происходит внутри сложной транзакции проведения ERP, платформа может интерпретировать его как критическую ошибку сеанса.
Чтобы избежать «вылетов» в самом конце работы пользователя (после того, как он заполнил документ), мы можем применить пессимистическую блокировку. В этом случае объект блокируется в момент начала редактирования. Разберем, как это реализовать программно. Нам необходимо вызвать метод Заблокировать(). Если другой пользователь уже открыл документ на редактирование, второй получит отказ сразу, а не в момент проведения.
Рассмотрим пример кода, который можно разместить в модуле формы документа или реализовать через расширение в процедуре ПриЧтенииНаСервере или ПриОткрытии:
&НаСервере
Процедура ЗаблокироватьОбъектНаСервере()
ОбъектСсылка = РеквизитФормыВЗначение("Объект");
Попытка
ОбъектСсылка.Заблокировать();
Исключение
ТекстОшибки = "Документ уже редактируется другим пользователем: " + ОписаниеОшибки();
ОбщийМодульКлиент.СообщитьПользователю(ТекстОшибки);
// Здесь можно установить флаг ТолькоПросмотр для формы
ЭтаФорма.ТолькоПросмотр = Истина;
КонецПопытки;
КонецПроцедуры
Часто «вылет» происходит из-за того, что ошибка блокировки не перехватывается программно и «пробрасывается» на уровень платформы. Чтобы этого избежать, используем конструкцию Попытка...Исключение. Рассмотрим, как правильно обработать запись объекта, чтобы при блокировке выводилось лишь предупреждение, а форма оставалась открытой.
Для реализации в расширении для процедуры ПередЗаписью на стороне сервера можно использовать следующий подход:
&НаСервере
Процедура Расш_ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
Попытка
// Пытаемся заблокировать объект перед началом транзакции записи
ТекущийОбъект.Заблокировать();
Исключение
Отказ = Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Не удалось записать документ, так как он заблокирован другим пользователем или процессом.";
Сообщение.Сообщить();
КонецПопытки;
КонецПроцедуры
Этот метод позволяет «мягко» прервать процесс записи, не доводя дело до аварийного завершения работы всей платформы.
Выясним причину, связанную со спецификой ERP. В этой конфигурации активно используются фоновые задания: расчет себестоимости, отложенное проведение, автоматическое формирование движений. Если пользователь проводит документ, а в этот момент фоновое задание пытается обновить регистры, связанные с этим же документом, возникает взаимоблокировка (deadlock).
В случае дедлока SQL-сервер выбирает одну из транзакций в качестве «жертвы» и откатывает её. Платформа 1С при получении сигнала об откате транзакции по причине дедлока может инициировать перезапуск сеанса. Чтобы минимизировать такие случаи, выполним следующие настройки:
EXCP (исключения) и TDEADLOCK. Это позволит увидеть, на какой именно таблице происходит конфликт.Проанализируем техническую составляющую. Существуют конкретные релизы платформы (например, в ветке 8.3.16 и 8.3.18), в которых была обнаружена ошибка: при возникновении конфликта управляемых блокировок клиентское приложение аварийно завершалось с дампом памяти.
Рекомендация: Убедитесь, что версия вашей платформы актуальна. Для ERP 2.4 рекомендуется использовать стабильные сборки 8.3.22 или выше. Обновление платформы часто само по себе устраняет проблему «вылетов», заменяя их штатным сообщением об ошибке Объект заблокирован.
Мы рассмотрели, что проблема аварийного завершения сеанса в 1С при блокировках объектов обычно вызвана либо изменениями в поведении современных версий платформы, либо отсутствием обработки исключений в коде. Для устранения проблемы рекомендуется:
Заблокировать().Попытка...Исключение.Применяя эти методы, мы обеспечим стабильную работу пользователей и предотвратим потерю данных из-за внезапных закрытий программы.