1с ошибка блокировки объекта объект уже заблокирован
Блокировка данных объекта для редактирования из кода
Область применения: управляемое приложение, обычное приложение.
1.1. Прежде чем изменять существующий объект информационной базы из кода на встроенном языке, следует предварительно его заблокировать (установить «блокировку данных для редактирования» или «объектную блокировку»), тем самым, во-первых, убедиться, не заблокирован ли он другими объектами, во-вторых, попытаться предотвратить его изменение другими пользовательскими сеансами (или другими экземплярами объекта в этом же сеансе).
В противном случае, если при изменении и записи из встроенного языка не устанавливать блокировку объекта на время редактирования, то может возникнуть, например, ситуация, когда пользователь не сможет сохранить свои изменения, если эти же самые данные были конкурентно изменены в другом сеансе.
При этом блокировка данных для редактирования не запрещает запись заблокированных данных в других пользовательских сеансах (или в других экземплярах объекта в этом же сеансе), а лишь не позволяет нескольким объектам одновременно установить блокировку одних и тех же данных. В отличие от транзакционных блокировок данных, пессимистическая блокировка данных для редактирования предназначена для обеспечения конкурентной работы пользователей с объектами информационной базы 1С:Предприятия (элементами справочников, документами и т.д.) Подробнее о блокировке данных для редактирования см. документацию по платформе 1С:Предприятие 8 .
1.2. Для блокировки данных для редактирования из встроенного языка следует вызывать метод объектов Заблокировать или метод глобального контекста ЗаблокироватьДанныеДляРедактирования .
«Не удалось заблокировать запись. Действие (изменение, удаление или блокировка записи) не выполнено. Ошибка блокировки объекта. Объект уже заблокирован: компьютер: <имя компьютера>, пользователь: <имя пользователя>, сеанс: <номер сеанса>, начат: <дата и время>, приложение: <тип клиентского приложения>».
Аналогичным образом, можно воспользоваться методом глобального контекста ЗаблокироватьДанныеДляРедактирования :
Пример № 2. Требуется пропустить обработку объекта, если он заблокирован для редактирования. При очередном вызове процедуры (например, из фонового или регламентного задания) будет предпринята повторная попытка изменения объекта.
ФайлОбъект = ТекущаяВерсия.ПолучитьОбъект();
// Выполнить блокировку объекта от изменения другими режимами или пользователями.
УстановитьПолноеНаименование = Истина;
Попытка
ФайлОбъект.Заблокировать();
Исключение
// в случае блокировки - не выполнять изменение объекта
УстановитьПолноеНаименование = Ложь;
// записать предупреждение в журнал регистрации
ЗаписьЖурналаРегистрации(НСтр("ru = 'Фоновое обновление имен файлов'", Метаданные.ОсновнойЯзык.КодЯзыка),
УровеньЖурналаРегистрации.Предупреждение,, ФайлОбъект, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
// Пропустить обработку объекта, если он заблокирован.
Если УстановитьПолноеНаименование Тогда
ФайлОбъект.ПолноеНаименование = ПолноеНаименование;
ФайлОбъект.Записать();
КонецЕсли;
1.3. При редактировании данных в формах, платформа 1С:Предприятие автоматически устанавливает блокировку объекта, указанного в качестве основного реквизита формы.
2. Не следует проверять блокировку объектов для редактирования в следующих случаях:
1С Предприятие 8.3.15.1656
режим совместимости 8.3.14
Работаю с расширением конфигурации.
Режим отладки включен.
Никак не могу понять что происходит. Вдруг внезапно выпадает ошибка:
При выполнении операции над расширение "Учет посетителей" возникла ошибка:
Не удалось заблокировать запись. Ну и так далее - полный текст на скрине.
Пытаюсь выполнить обновление идентификаторов объектом метаданных либо обновление конфигурации (через ключ запуска) - такая же обшибка, обновление конфигурации зависает и НЕ выполняется.
Никак не могу отловить закономерность. Расширение то работает, то ругается такой ошибкой.
Помогает только полное удаление расширения со всеми данными.
Проблему удалось обойти, но не совсем понятно на сколько это корректно.
В общем делюсь что удалось нарыть. В текущей версии конфы используется какой-то устаревший метод обновления ИД объектов МД при котором все расширения сначала удаляются (с предварительным сохранением их данных), а затем восстанавливаются из хранилища.
На сколько я понял, это какая-то особенность совместимости 8.3.6 потому что в релизе КА2.0 с совместимостью 8.3.14 ничего такого нет в аналогичной процедуре модуля менеджера справочника ИД объектом МД.
В общем я просто отключил вызов исключения в случае невозможностиудаления расширения и после этого включил расширение, успешно обновил справочник ИД объектов МД и отчет открылся.
т.е. просто отключил команду вызывающую исключение
Пробовал делать расширение неактивным - не помогает.Конфигурация типовая - украинская локализация КА2.0. Ошибка возникает при обращении к одному отчету. Даже если открыть его как внешний файл - всё равно возникает ошибка.
Исключение происходит в этой функции.
Типовая конфигурация зачем-то пытается удалить расширения. Приблизительно догадываюсь что это как-то связано с обновлением справочника "Идентификаторы объектов МД", но не понимаю логики.
(7) при активном расширении ни под каким пользователем не дает зайти с такой ошибкой
в базе больше никого нет, конфигуратор ЗАКРЫТ
Если открыт конфигуратор, но ВСЕ расширения закрыты, то запуск 1С в режиме отладки позволяет загрузиться. Все объекты расширения открываются нормально, а при попытке открыть отчёт выдает туже ошибку. Причем даже при попытке открыть внешний отчет тоже ошибка.
Я подозреваю что при открытии отчётов происходит попытка обновить элементы справочника идентификаторы объектов расшерений (и/или метаданных) и уже это действие вызывает ошибку.
PS. Ошибка возникает при открытии ЛЮБОГО внешнего отчета. а так же при открытии меню "Отчеты" любого раздела (Казначенийство, Продажи и т.п.).
Т.е. таки точно проблема в том, что не может отработать обновление идентификаторов объектом МД.
(11) Я не знаю с чем это связано, есть обсуждение на партнерском форуме (у меня нет доступа туда), но советуют при отладке расширения запускать отладку из конфигуратора с параметром /РежимОтладки. И этот параметр не связан режимом debug на сервере.Проблему удалось обойти, но не совсем понятно на сколько это корректно.
В общем делюсь что удалось нарыть. В текущей версии конфы используется какой-то устаревший метод обновления ИД объектов МД при котором все расширения сначала удаляются (с предварительным сохранением их данных), а затем восстанавливаются из хранилища.
На сколько я понял, это какая-то особенность совместимости 8.3.6 потому что в релизе КА2.0 с совместимостью 8.3.14 ничего такого нет в аналогичной процедуре модуля менеджера справочника ИД объектом МД.
В общем я просто отключил вызов исключения в случае невозможностиудаления расширения и после этого включил расширение, успешно обновил справочник ИД объектов МД и отчет открылся.
т.е. просто отключил команду вызывающую исключение
(13) в конечном итоге осталось невыясненным почему расширение не удалялось программно, но разработчики типовой конфигурации не правы в том, что вводят пользователя в заблуждение тем, что допускают что расширение может не удаляться только из-за того, что оно занято конфигуратором. Написали бы просто - не удаляется расширение, возможная причина конфигуратор.Опять у меня проблема с этой частью. Сейчас с " Расширение.Удалить();" когда пытался сделать "/С ЗапуститьОбновлениеИнформационнойБазы". Для файловой все работает, для SQL - эта строка просто не выполняется и все валится. В целом проблема решилась пришлось использовать: Справочники.ИдентификаторыОбъектовМетаданных.ВыполнитьОбновлениеДанных(Истина, ЛОЖЬ,"Полный"); плюс еще кучу мест пришлось поменять.
Очень много времени уходит на игрульки такого плана.
Очень надеюсь, что разработчики BAS КУП все же обновят этот модуль да и версию режима совместимости поставят "не использовать" или "8.3.18", "8.3.20". В текущей версии имеем какой-то замкнутый круг - можем использовать кучу всяких классных фишек расширений - уже практически все метаданные имеют представление в расширениях и с другой стороны чтобы их использовать - надо поднять версию конфигурации. А как ее поднять если из-за этого валятся ошибки? А уже и не сильно уверен в правильности их использования. Вот с BAS КУП (и др. наверно) более высокого режима совместимости я бы 100% рекомендовал клиентам. А сейчас - хз
Вот простейший пример на Delphi отображения заблокированных объектов в 1С.
procedure TForm1.Button1Click(Sender: TObject);
var
i : integer;
begin
h:=FileOpen('d:ПроверкаКонфликтов1sjourn.$lk',fmOpenRead+fmShareDenyNone);
showmessage(inttostr(h));
for i:=0 to 10000 do
if LockFile(h,i,0,1,0) then
begin
UnlockFile(h,i,0,1,0);
end
else
begin
Memo1.Lines.Add(IntToStr(i)+' - Locked');
end;
FileClose(h);
end;
Для того чтобы понять, какой у документа номер и вид для этого достаточно выполнить простейший select. SELECT IDDOCDEF AS ТипДокумента, IDDOC AS ВнутреннийИдентификатор, DOCNO AS НомерДокумента
FROM _1SJOURN
WHERE (ROW_ID = @i)
Где @i это номер байта полученный вышеописанной процедурой.
Для справочников это будет файл не 1sjourn.$lk а scXXX.$lk где ХХХ – внутренний идентификатор объекта метаданных.
Также нужно отметить, что блокировку установить или снять в пределах своей сессии можно с помощью метода Блокировать(). Значение, которое возвращает этот метод собственно и указывает на то, заблокирован он или нет. Нужно отметить, что пример приведенный на Delphi, гораздо производительней, т.к. в этом случае не нужно открывать выборку данных и проверять каждый элемент на блокировку, а достаточно лишь взять заведомо заблокированные байты и сопоставить их объектам данных в 1С.
Возникает вопрос: а можно ли снимать блокировки не из своей сессии, и что произойдет, например, если мы попытаемся удалить файл 1sjourn? Сразу нужно отметить, что просто так удалить нам его не удастся, если он задействован хотя бы в одном сеансе 1С. Даже если мы возьмем и удалим все хэндлы на него и затем удалим его, то и в этом случае нас постигнет неудача т.к. в этом случае при обращении ко всем документа будет появляться надпись «запись заблокирована». Косвенные причины этого понятны, неудача в LockFile(h,i,0,1,0) ,а в данном случае хэндл теряется, 1С интерпретируется как блокировка объекта. И даже если мы создадим заново этот файл, то блокировок не будет только у тех клиентов, которые загрузили 1С после создания файла. Скорее всего, это происходит потому, что 1С хранит в локальной переменной информацию об открытии файла. Если он уже открывался, то 1С не пытается за нового его открыть и получить новый хендл. Однако принципиальная возможность создания такого менеджера управления блокировками существует(возможно, он уже и написан).
При использовании материалов данной статьи обязательна ссылка на информационный ресурс и автора статьи.
Читайте также: