Материал сайта www.softpoint.ru/
В предыдущей статье по "гибким" блокировкам, я пожалуй, не сделал акцент на то ,что блокировки в контексте 1С бываю двух видов. Первый вид - это блокировки данных на уровне SQL Servera. Второй вид - это блокировки объектов 1С (клиентских форм). Хочу исправить свою ошибку и остановиться на описании второго вида блокировок подробнее.
Для чего вообще 1С реализовала внутренний механизм блокировок ? Ну во-первых для того, чтобы не решать вопрос разрешения конфликтов отображения и записи данных из разных экранных форм одного и того же объекта. То есть предполагается, что если пользователь открыл расходную накладную №5, то никто другой не сможет открыть экранную форму этой накладной, пока он ее не закроет. На попытку открыть документ выведется на экран сообщение «Запись заблокирована». Аналогичные по смыслу сообщения будут выводиться в обработках при попытках изменить объект данных, который заблокирован.Это кстати многие не учитывают в своих обработках.
Давайте теперь попытаемся понять, как устроен механизм «внутренней» блокировки 1С. Ну во-первых, при каждом открытии формы документа создается, если он еще не существует, временный файл 1sjourn.$lk. Размер этого файла всегда 0 и казалось бы в нем вряд ли может быть заложена информация по блокировкам. На самом деле это заблуждение. 1С используя функцию LockFile блокирует конкретный байт в фале указывая тем самым, что тот или иной документ заблокирован. Номер байта соответствует Row-Id(первичный ключ) данного документа. Перед открытием формы или исполнением метода объекта 1С пытается заблокировать байт. Если попытка проходит, то он остается заблокированным до завершения операции, если же нет - то выдается соответствующее сообщение.
Вот простейший пример на 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С не пытается за нового его открыть и получить новый хендл. Однако принципиальная возможность создания такого менеджера управления блокировками существует(возможно, он уже и написан).
При использовании материалов данной статьи обязательна ссылка на информационный ресурс и автора статьи.
Начать дискуссию