При переходе с файловой версии базы данных на клиент-серверный вариант (MS SQL) разработчики часто сталкиваются со специфической ошибкой: При выполнении транзакции произошла ошибка! Объект заблокирован. Эта ситуация особенно болезненна, если база самописная и активно использует создание новых элементов справочников прямо из форм выбора или подбора. Давайте разберем, почему это происходит и как исправить поведение системы.
В файловой версии 1С 7.7 управление блокировками лежит на самой платформе, которая работает с файлами БД. В SQL-версии ситуация иная: за блокировки отвечает непосредственно MS SQL Server. Когда вы открываете форму выбора справочника и пытаетесь из неё создать новый элемент, происходит цепочка событий:
ОткрытьФорму).Разберем способы, которые помогут избежать появления этой ошибки в коде вашей конфигурации.
Самый надежный способ — исключить возможность создания новых элементов справочника непосредственно в форме, которая была открыта для выбора значения. Интерактивное создание объектов «на лету» в форме подбора — это частая причина нестабильности на SQL.
Рекомендация: Сделайте создание нового элемента отдельным процессом. Например, добавьте кнопку «Создать» на форму документа, которая будет открывать карточку справочника в отдельном окне. После записи элемента пользователем, используйте механизм оповещения для обновления данных в документе.
Если вам все же необходимо открывать форму для создания, используйте штатный механизм обмена данными между формами. Вместо того чтобы пытаться записать ссылку напрямую в реквизит формы документа, примените оповещения.
В форме создания элемента после успешной записи вызовите метод:
// В модуле формы элемента справочника
Оповестить("ОбъектСоздан", НовыйОбъектСсылка, "ИдентификаторКонтекста");
А в основной форме документа обработайте это событие:
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "ОбъектСоздан" Тогда
// Присваиваем значение реквизиту
РеквизитДоговора = Параметр;
КонецЕсли;
КонецПроцедуры
Проанализируем текущий подход к вызову формы выбора в коде. Часто разработчики используют ОткрытьФорму с передачей параметров. Убедитесь, что вы не вызываете блокирующие функции внутри ПриОткрытии самой формы списка.
Разберем пример кода, который часто встречается в конфигурациях:
Процедура ПриНачалеВыбораЗначения(ИД, Флаг)
Если ИД = "ПараметрыДляФормированияПлатежныхДокументов" Тогда
Флаг = 0; // Отменяем стандартный выбор
СЗ = СоздатьОбъект("СписокЗначений");
// ... установка параметров отбора ...
ОткрытьФорму("Справочник.ПараметрыДляФормированияПлатежныхДокументов#" + Контрагент, СЗ);
КонецЕсли;
КонецПроцедуры
Если в ПриОткрытии вызываемой формы есть сложная логика, выполняющая запросы к БД, она должна быть максимально оптимизирована. Помните: лишние транзакции внутри ПриОткрытии в среде SQL-сервера крайне нежелательны.
Если ошибка возникает даже при одиночной работе, обратитесь к настройкам MS SQL Server. Для корректной работы 1С 7.7 уровень изоляции должен быть Read Committed. Если уровень выше (например, Serializable), сервер будет блокировать ресурсы даже для чтения данных, которые были изменены, но не зафиксированы, что и приводит к ошибке Объект заблокирован.
Подведем итог: если вы столкнулись с этой ошибкой, в первую очередь попробуйте:
ПриОткрытии форм на наличие лишних транзакций.Оповестить для передачи данных между формами, чтобы полностью разрывать цепочку незавершенных транзакций при создании новых объектов.Помните, что архитектурные решения, заложенные в конфигурацию, должны учитывать транзакционную модель SQL-сервера. Разделение процессов выбора и создания — это не просто хороший тон программирования, это залог стабильности вашей системы.