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С не пытается за нового его открыть и получить новый хендл. Однако принципиальная возможность создания такого менеджера управления блокировками существует(возможно, он уже и написан).
При использовании материалов данной статьи обязательна ссылка на информационный ресурс и автора статьи.
1С:Предприятие 8.1 (8.1.14.72)+SQL
Люди добрые помогите )
с помощью метода "УстановитьБлокировкуУстановкиСоединений()" устанавливаю блокировку, при чтении методом "ПолучитьБлокировкуУстановкиСоединений()" говорит что блокировка установлена, но при этом без проблем дает зайти в базу!
всегда работало, а тут нет. где подвох, может какие настройки в консоли серверов или еще где .
(0)Я думаю будет логично, если система пустит пользователя с правами "Обновление конфигурации базы данных".
причем здесь права, база должна блокироваться для всех, и вход должен выполнятся только с указанным ключем
файлик создается? забыл расширение, который должен создаваться при блокировке
Время блокировки проверь. Мало ли, а вдруг установлено.
с параметрами блокировки изгалялся как можно, результат один (
(5) Ты код из СП:
----------------------------------------------------------------
---------------------------------------------------------------------
типа вставил и хочешь сказать ничего? Не верю.
(5) Через COM блокировку проверяешь? После запуска заблокированной базы что возвращает ПолучитьБлокировкуУстановкиСоединений?
ЗЫ (6)+1
(7) методом ПолучитьБлокировкуУстановкиСоединений() возвращает то что было установлено методом УстановитьБлокировкуУстановкиСоединений()
(11) А конкретнее. В предприятии интерактивно запустил обработку, которая установила блокировку. Затем закрыл предприятие, повторно открыл без ключа в командной строке и через код проверил в отладчике (или обработкой), что блокировка установлена и её параметры?
(12) да, обработка внешняя (стандартная из УПП), установл параметры, закрываю обработку, потом снова открываю (она считывает при открытии параметры блокировки) - вывод что все установленно как надо и в отлатчике тоже проверил - параметры установлены. Но заходить при этом все-равно дает.
(13) Куда дает заходить - в обработку? Базу закрываешь или только обработку закрываешь?
ЗЫ Пока что по твоим описаниям ничего не понятно .
(15) еще раз:
1) установил блокировку обработкой (выставил период и др. параметры)
3) открываю базу, и она открывается. под любым пользователем
4) открываю снова обработку что-бы проверить параметры блокировки - они установлены
(16) Набери в табло после захода в заблокированную базу
ПолучитьБлокировкуУстановкиСоединений().Установлена
ПолучитьБлокировкуУстановкиСоединений().КодРазрешения
ошибка не в коде 99% ) ведь работает-же в файловом варианте
может в SQL загвоздка, там может как-то можно запретить такие блокировки .
Пользователь ругается, что не всегда отрабатывает блокировка,бывает что могут два пользователя редактировать.
Собственно вопрос, почему в коде написано в одном месте Заблокировать и Разблокировать ?
Кто то же сделал это не с проста, думаю как раз дело в Разблокировать.
Плюс как можно проверить в одном конфигураторе вход двух разных пользователей?
Тут вопрос в другом , нужно при открытии формы документа тогда дописывать что то типа
Поправка, в УФ надо в процедуре при ПриСозданииНаСервереэто делать
И при закрытии документа, его разблокировать. тогда этот метод прокатит у вас , а иначе ничего не отработает.
он блокируется и разблокируется в одной "попытке"? " ТЧ есть процедура Выбора" - т.е. выбрали и блокировка снялась.
1.1. Прежде чем изменять существующий объект информационной базы из кода на встроенном языке, следует предварительно его заблокировать (установить «блокировку данных для редактирования» или «объектную блокировку»), тем самым, во-первых, убедиться, не заблокирован ли он другими объектами, во-вторых, попытаться предотвратить его изменение другими пользовательскими сеансами (или другими экземплярами объекта в этом же сеансе).
В противном случае, если при изменении и записи из встроенного языка не устанавливать блокировку объекта на время редактирования, то может возникнуть, например, ситуация, когда пользователь не сможет сохранить свои изменения, если эти же самые данные были конкурентно изменены в другом сеансе.
При этом блокировка данных для редактирования не запрещает запись заблокированных данных в других пользовательских сеансах (или в других экземплярах объекта в этом же сеансе), а лишь не позволяет нескольким объектам одновременно установить блокировку одних и тех же данных.
Сервис - Параметры - Запуск 1с
Можно выбрать пользователя под которым запускать 1с для отладки
При этом блокировка данных для редактирования не запрещает запись заблокированных данных в других пользовательских сеансах (или в других экземплярах объекта в этом же сеансе), а лишь не позволяет нескольким объектам одновременно установить блокировку одних и тех же данных.
По поводу этого, по сути устанавливается же блокировка объекта, как тогда пользователь ещё может зайти ? Выходит дело всё-таки в блокировка и разблокировке в одном месте и достаточно убрать разблокировать? этот код у вас проверяет есть блокировка или нет а не блокирует поэтому и есть в одном месте блокировка и разблокировка (если объект заблокирован другим пользователем - то попадаете в исключение, а если свободен - то ничего не происходит) этот код у вас проверяет есть блокировка или нет а не блокирует (5) То есть имеет смысл после Разблокировать (); Написать снова объект.Заблокировать? И разблакировка автоматически снимется после записи объекта ? (7) Я бы сказал, такое возможно. Но это не есть хорошая практика. Для этого есть метод Заблокирован() .
Исключение, должно оставаться исключением, и не гоже использовать его в качестве управляющего блока. (8) И в каком же мне месте проверять на методом Заблокирован(), если у меня идёт блокировка,а после сразу разблокировка. ?
Но в любом случае объект тогда должен блокироваться программно, методом заблокировать(), иначе вы ничего не проверите.
(10) Но если я принудительно не заблокирую, то и блокировки не будет.
И что вы подразумеваете после "Тогда" писать ?
Видимо не дописали Вы,быстро ответил я.
Вот именно меня и интересует когда ставить Заблокировать ? После моей конструкции?
А при закрытии документов делать Разблокировать ?
Тут вопрос в другом , нужно при открытии формы документа тогда дописывать что то типа
Поправка, в УФ надо в процедуре при ПриСозданииНаСервереэто делать
И при закрытии документа, его разблокировать. тогда этот метод прокатит у вас , а иначе ничего не отработает.
(14) В итоге сделал при Выборе документов принудительную Блокировку.А при выходе,закрытии написал следующее:
Насколько это корректно ?
При закрытии формы документа ? если да то вполне нормально..только блокировку я бы прописал в при создании, потому как открыть документы можно же не только из этой обработки,
(19) У пользователя только три варианта закрыть форму, это выйти в список документов, либо на крестик в верхнем углу обработки, либо кнопка "Выйти". Соответственно везде и добавил этот кусок призакрытии. (22) Короче, всё зависит от вашего конкретного случая. Что вы там делаете мы не знаем, а значит будет у вас блокировка или нет, думайте сами. Главное запомните. Блокировка действует в период: от вызова "Заблокировать" - до конца процедуры её вызвавшей. Соответственно устанавливать или проверять блокировку на форме не имеет практического смысла, в большинстве случаев использования. Но вполне возможно, что в вашем конкретном случае, это и имеет практическое применение. Блокировка действует в период: от вызова "Заблокировать" - до конца процедуры её вызвавшейоткуда такая инфа, не подскажете? Не могу найти подтверждения
(14) Этот код не будет работать. Т.к. в данном случае ЭтотОбъект - это УправляемаяФорма. РеквизитФормыВЗначение("Объект").Заблокировать(). Тоже не сработает. Т.к. блокировка работает только на время выполнения процедуры. Соответственно после выполнения "ПередОткрытием" ничто не мешает другому сеансу/коду изменить объект, до того как первый пользователь нажмёт кнопку "Записать". (18) Ну у меня у формы реквизит ДокументОбъект.ЗаказПокупателя.Его и блокирую.
А по другому пользователи как кроме выбрать из списка и создать новый ничего больше не могут. Только записать и провести прямо в списке. Но так делать не будут думаю,хотя.. заставили задуматься Вы меня :) (25) В обычных формах, объект живёт на клиенте. В данном случае всё упрощается. Делайте блокировку в модуле объекта. А разблокируйте ПослеЗаписи.
Я поправил под УФ, просто код скопировал под обычные формы.
Там при создании на сервере, блокироваться должен объект, тогда пока формы будет открыта объект связанный с формой тоже будет заблокирован, кстати нигде не сказано что блокировка действует только на время выполнения процедуры. откуда такие данные ? По идее блокировка на объект должна действовать пока вы его не разблокируете, или сам объект( в данном случае объект открытого документа ) не будет удален программой, т.е. пользователь закроет форму.
(28) Не, забираю свои слова обратно. Не работает ПриСозданииНаСервере. Всё равно объект не блокируется. Почему тогда возникала ошибка ("объект не выбран") не понятно.
кстати нигде не сказано что блокировка действует только на время выполнения процедуры. откуда такие данныеЭкспериментально. Открыл два окна. В одном окне заблокировал, попробовал во втором. Блокировка не сработала. Поставил на паузу после блокировки. Попробовал заблокировать во втором - блокировка сработала. В общем эти сведения мне дебагер сообщил
(28) Продолжил, дальше исследовать поведение метода "Заблокировать".
1е. РеквизитФормыВЗначение("Объект") не имеет ни какого эффекта. Блокировка не устанавливается
2е. Заблокировать() - работает только пока исполняется процедура её вызвавшая
3е. Заблокирован() - работает только для сеанса его установившего. В остальных случаях всегда даёт ответ - "НЕТ"
4е. Объект блокируется автоматически только после записи объекта, и пока форма открыта (в чём смысл, не понятно)
Было проверено на совершенно разных версиях платформ. В клиент-серверном и файловом вариантах. Так что единственно правильным вариантом использования будет всё же изначальный:
Блокировка данных объекта для редактирования из кода
Область применения: управляемое приложение, обычное приложение.
1.1. Прежде чем изменять существующий объект информационной базы из кода на встроенном языке, следует предварительно его заблокировать (установить «блокировку данных для редактирования» или «объектную блокировку»), тем самым, во-первых, убедиться, не заблокирован ли он другими объектами, во-вторых, попытаться предотвратить его изменение другими пользовательскими сеансами (или другими экземплярами объекта в этом же сеансе).
В противном случае, если при изменении и записи из встроенного языка не устанавливать блокировку объекта на время редактирования, то может возникнуть, например, ситуация, когда пользователь не сможет сохранить свои изменения, если эти же самые данные были конкурентно изменены в другом сеансе.
При этом блокировка данных для редактирования не запрещает запись заблокированных данных в других пользовательских сеансах (или в других экземплярах объекта в этом же сеансе), а лишь не позволяет нескольким объектам одновременно установить блокировку одних и тех же данных. В отличие от транзакционных блокировок данных, пессимистическая блокировка данных для редактирования предназначена для обеспечения конкурентной работы пользователей с объектами информационной базы 1С:Предприятия (элементами справочников, документами и т.д.) Подробнее о блокировке данных для редактирования см. документацию по платформе 1С:Предприятие 8 .
1.2. Для блокировки данных для редактирования из встроенного языка следует вызывать метод объектов Заблокировать или метод глобального контекста ЗаблокироватьДанныеДляРедактирования .
«Не удалось заблокировать запись. Действие (изменение, удаление или блокировка записи) не выполнено. Ошибка блокировки объекта. Объект уже заблокирован: компьютер: <имя компьютера>, пользователь: <имя пользователя>, сеанс: <номер сеанса>, начат: <дата и время>, приложение: <тип клиентского приложения>».
Аналогичным образом, можно воспользоваться методом глобального контекста ЗаблокироватьДанныеДляРедактирования :
Пример № 2. Требуется пропустить обработку объекта, если он заблокирован для редактирования. При очередном вызове процедуры (например, из фонового или регламентного задания) будет предпринята повторная попытка изменения объекта.
ФайлОбъект = ТекущаяВерсия.ПолучитьОбъект();
// Выполнить блокировку объекта от изменения другими режимами или пользователями.
УстановитьПолноеНаименование = Истина;
Попытка
ФайлОбъект.Заблокировать();
Исключение
// в случае блокировки - не выполнять изменение объекта
УстановитьПолноеНаименование = Ложь;
// записать предупреждение в журнал регистрации
ЗаписьЖурналаРегистрации(НСтр("ru = 'Фоновое обновление имен файлов'", Метаданные.ОсновнойЯзык.КодЯзыка),
УровеньЖурналаРегистрации.Предупреждение,, ФайлОбъект, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
// Пропустить обработку объекта, если он заблокирован.
Если УстановитьПолноеНаименование Тогда
ФайлОбъект.ПолноеНаименование = ПолноеНаименование;
ФайлОбъект.Записать();
КонецЕсли;
1.3. При редактировании данных в формах, платформа 1С:Предприятие автоматически устанавливает блокировку объекта, указанного в качестве основного реквизита формы.
2. Не следует проверять блокировку объектов для редактирования в следующих случаях:
Читайте также: