Добрый день всем.
Есть обработка в которой можно выбрать из списка либо "Заказы покупателя" или "Реализация товаров и услуг".
У этой ТЧ есть процедура Выбора:

```1c
    Попытка
    Объект.Заблокировать();
    Объект.Разблокировать();
    .....
    Исключение
    Предупрждение("Документ уже редактируется");
    Конец
```

Пользователь ругается, что не всегда отрабатывает блокировка,бывает что могут два пользователя редактировать.

Собственно вопрос, почему в коде написано в одном месте Заблокировать и Разблокировать ?
Кто то же сделал это не с проста, думаю как раз дело в Разблокировать.
Плюс как можно проверить в одном конфигураторе вход двух разных пользователей?
---
А вы и так его не блокируете, так как у вас все происходит в попытке, не смогли заблокировать, вышли в исключение, смогли..то и разблокировали сразу,
Тут вопрос в другом , нужно при открытии формы документа тогда дописывать что то типа

```1c
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // - - - Заблокируем от работающих остальных

    Попытка
    ЭтотОбъект.Заблокировать();
    Исключение
    Сообщить("Форма документа уже открыта другим пользователем!");
    Отказ = Истина;
    Возврат;
    КонецПопытки;
```

Поправка, в УФ надо в процедуре при ПриСозданииНаСервереэто делать

И при закрытии документа, его разблокировать. тогда этот метод прокатит у вас , а иначе ничего не отработает...
---
он блокируется и разблокируется в одной "попытке"? " ТЧ есть процедура Выбора" - т.е. выбрали и блокировка снялась...

1.1. Прежде чем изменять существующий объект информационной базы из кода на встроенном языке, следует предварительно его заблокировать (установить «блокировку данных для редактирования» или «объектную блокировку»), тем самым, во-первых, убедиться, не заблокирован ли он другими объектами, во-вторых, попытаться предотвратить его изменение другими пользовательскими сеансами (или другими экземплярами объекта в этом же сеансе).

В противном случае, если при изменении и записи из встроенного языка не устанавливать блокировку объекта на время редактирования, то может возникнуть, например, ситуация, когда пользователь не сможет сохранить свои изменения, если эти же самые данные были конкурентно изменены в другом сеансе.

При этом блокировка данных для редактирования не запрещает запись заблокированных данных в других пользовательских сеансах (или в других экземплярах объекта в этом же сеансе), а лишь не позволяет нескольким объектам одновременно установить блокировку одних и тех же данных.

Сервис - Параметры - Запуск 1с
Можно выбрать пользователя под которым запускать 1с для отладки
---
Да.В одной попытке, хотел поменять, но зачем то это же сделали же.. Отсюда и вопросы..
При этом блокировка данных для редактирования не запрещает запись заблокированных данных в других пользовательских сеансах (или в других экземплярах объекта в этом же сеансе), а лишь не позволяет нескольким объектам одновременно установить блокировку одних и тех же данных.
По поводу этого, по сути устанавливается же блокировка объекта, как тогда пользователь ещё может зайти ? Выходит дело всё-таки в блокировка и разблокировке в одном месте и достаточно убрать разблокировать?
---
может здесь, что подскажет -
Методическая поддержка для разработчиков и администраторов 1С:Предприятия 8 :: Блокировки данных в 1С:Предприятии 8
---
но зачем то это же сделали же этот код у вас проверяет есть блокировка или нет а не блокирует поэтому и есть в одном месте блокировка и разблокировка (если объект заблокирован другим пользователем - то попадаете в исключение, а если свободен - то ничего не происходит)
---
этот код у вас проверяет есть блокировка или нет а не блокирует
это - зачёт (както - я даже не оценил, это)
---
То есть имеет смысл после Разблокировать (); Написать снова объект.Заблокировать? И разблакировка автоматически снимется после записи объекта ?
---
Я бы сказал, такое возможно. Но это не есть хорошая практика. Для этого есть метод Заблокирован().
Исключение, должно оставаться исключением, и не гоже использовать его в качестве управляющего блока.
---
И в каком же мне месте проверять на методом Заблокирован(), если у меня идёт блокировка,а после сразу разблокировка. ?
---
Вместо, Этих двух, ставите вызов
```1c
    Если объект.Заблокирован() Тогда
```

Но в любом случае объект тогда должен блокироваться программно, методом заблокировать(), иначе вы ничего не проверите...
---
Но если я принудительно не заблокирую, то и блокировки не будет.

И что вы подразумеваете после "Тогда" писать ?

Видимо не дописали Вы,быстро ответил я.
Вот именно меня и интересует когда ставить Заблокировать ? После моей конструкции?
А при закрытии документов делать Разблокировать ?
---
А вы и так его не блокируете, так как у вас все происходит в попытке, не смогли заблокировать, вышли в исключение, смогли..то и разблокировали сразу,
Тут вопрос в другом , нужно при открытии формы документа тогда дописывать что то типа

```1c
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // - - - Заблокируем от работающих остальных

    Попытка
    ЭтотОбъект.Заблокировать();
    Исключение
    Сообщить("Форма документа уже открыта другим пользователем!");
    Отказ = Истина;
    Возврат;
    КонецПопытки;
```

Поправка, в УФ надо в процедуре при ПриСозданииНаСервереэто делать

И при закрытии документа, его разблокировать. тогда этот метод прокатит у вас , а иначе ничего не отработает...
---
В итоге сделал при Выборе документов принудительную Блокировку.
А при выходе,закрытии написал следующее:

```1c
    Попытка
    Если Объект.Заблокирован Тогда
    Объект.Разблокировать();
    конецесли
    Исключение
    Конецпопытки
```

Насколько это корректно ?
---
А при выходе,закрытии написал следующее:

При закрытии формы документа ? если да то вполне нормально..только блокировку я бы прописал в при создании, потому как открыть документы можно же не только из этой обработки,
---
У пользователя только три варианта закрыть форму, это выйти в список документов, либо на крестик в верхнем углу обработки, либо кнопка "Выйти". Соответственно везде и добавил этот кусок призакрытии.
---
Короче, всё зависит от вашего конкретного случая. Что вы там делаете мы не знаем, а значит будет у вас блокировка или нет, думайте сами. Главное запомните. Блокировка действует в период: от вызова "Заблокировать" - до конца процедуры её вызвавшей. Соответственно устанавливать или проверять блокировку на форме не имеет практического смысла, в большинстве случаев использования. Но вполне возможно, что в вашем конкретном случае, это и имеет практическое применение.
---
Блокировка действует в период: от вызова "Заблокировать" - до конца процедуры её вызвавшей

откуда такая инфа, не подскажете? Не могу найти подтверждения
---
я проверил на практике, все действительно так
---
Этот код не будет работать. Т.к. в данном случае ЭтотОбъект - это УправляемаяФорма. РеквизитФормыВЗначение("Объект").Заблокировать(). Тоже не сработает. Т.к. блокировка работает только на время выполнения процедуры. Соответственно после выполнения "ПередОткрытием" ничто не мешает другому сеансу/коду изменить объект, до того как первый пользователь нажмёт кнопку "Записать".
---
Ну у меня у формы реквизит ДокументОбъект.ЗаказПокупателя.
Его и блокирую.
А по другому пользователи как кроме выбрать из списка и создать новый ничего больше не могут. Только записать и провести прямо в списке. Но так делать не будут думаю,хотя.. заставили задуматься Вы меня :)
---
Забыл упомянуть, это обычные формы.
---
В обычных формах, объект живёт на клиенте. В данном случае всё упрощается. Делайте блокировку в модуле объекта. А разблокируйте ПослеЗаписи.
---
ЭтотОбъект - это Управл
Я поправил под УФ, просто код скопировал под обычные формы...
Там при создании на сервере, блокироваться должен объект, тогда пока формы будет открыта объект связанный с формой тоже будет заблокирован, кстати нигде не сказано что блокировка действует только на время выполнения процедуры...откуда такие данные ? По идее блокировка на объект должна действовать пока вы его не разблокируете, или сам объект( в данном случае объект открытого документа ) не будет удален программой, т.е. пользователь закроет форму...
---
Не, забираю свои слова обратно. Не работает ПриСозданииНаСервере. Всё равно объект не блокируется. Почему тогда возникала ошибка ("объект не выбран") не понятно.

кстати нигде не сказано что блокировка действует только на время выполнения процедуры...откуда такие данные

Экспериментально. Открыл два окна. В одном окне заблокировал, попробовал во втором. Блокировка не сработала. Поставил на паузу после блокировки. Попробовал заблокировать во втором - блокировка сработала. В общем эти сведения мне дебагер сообщил
---
Продолжил, дальше исследовать поведение метода "Заблокировать".
1е. РеквизитФормыВЗначение("Объект") не имеет ни какого эффекта. Блокировка не устанавливается
2е. Заблокировать() - работает только пока исполняется процедура её вызвавшая
3е. Заблокирован() - работает только для сеанса его установившего. В остальных случаях всегда даёт ответ - "НЕТ"
4е. Объект блокируется автоматически только после записи объекта, и пока форма открыта (в чём смысл, не понятно)

Было проверено на совершенно разных версиях платформ. В клиент-серверном и файловом вариантах. Так что единственно правильным вариантом использования будет всё же изначальный:
---
работает только для сеанса его установившего. В остальных случаях всегда даёт ответ - "НЕТ
Тут немного другое, так как Заблокировать()..это серверный метод..то есть свой подвох...т.е. объект удаляется при выходе из серверной функции..и создается заново при входе в нее...соответственно и блокировать в УФ возможно только тогда пока сам объект на сервере существует, как только объект удаляется с сервера..блокировка тоже снимается...
Попробовал через обработку созданием документа объекта методом ПолучитьОбъект() но как только будет произведен выход из серверной функции и объект удалиться блокировка снимется,
Кстати есть функция
```1c
    ЗаблокироватьДанныеДляРедактирования(Документ,,УникальныйИдентификатор)
```
;
Попробовал присозданииНаСервере, Формы документа установить блокировку, а потом в обработке проверку сделал , выдало что заблокировано
---
Да, это вполне полное и исчерпывающее объяснение, почему метод Заблокировать, действует только в пределах функции. От себя добавлю, что клиент 1С работает в режиме Запрос-Ответ, в ходе которого заново создаётся пользовательское окружение. За исключением параметров сеанса, которые хранятся в отдельном серверном контексте - сессии (сеанс). Соответственно при каждом действии пользователя мы имеем дело каждый раз с другим объектом. А ранее установленные состояния объектов БД, сбрасываются.
---
изначальный это какой ?
---
Да блин, точно, ПриСозданииНаСервере даёт желаемый эффект, правда несколько особенно. Если заблокировать объект в этот момент, то другой сеанс, вообще не сможет получить Объект (ПолучитьОбъект()). Х.з. с чем связано. Не документированная возможность :)
Не. Эта блокировка у меня только раз сработала. Дальше эффекта нет.
---
Приведенный вами код, занимается только этим - проверкой заблокированности объекта. Его можно полностью заменить на код:

```1c
    Если Объект.Заблокирован() Тогда
    Предупрждение("Документ уже редактируется");
    КонецЕсли;
```

Для блокировки изменений нужно записать так:

```1c
    Если Объект.Заблокирован() Тогда
    Предупрждение("Документ уже редактируется");
    Иначе
    Объект.Заблокировать()
    КонецЕсли;
```

Но эта блокировка действует только в пределах "транзакции" (пока платформа исполняет ветку кода вызвавшую эту блокировку). И только если вызвал её серверный код (обработка). Т.е. в случае с управляемыми формами, это будет работать не всегда. Например, если блокировку вызовает код управляемой формы, то она просто не сработает (не заблокирует изменения для других пользователей). Или если блокировка наложена уже после открытия формы, это не возымеет никакого эффекта.
---
К сожалению, гарантированно защитить данные от попыток изменения в интерактивном режиме нельзя. Т.к. пользовательские сеансы ничего не знают, о других сеансах. А сервер не знает, что творится на клиенте у пользователя. Тут пожалуй можно воспользоваться системой взаимодействия (чатом), для оповещения "миру", что тот или иной объект заблокирован для изменения (интерактивно)
---
А как я описал в (15) не будет отрабатывать разве правильно ? хм
---
Да работать не будет. Как только код выйдет из процедуры, блокировка снимется. И я так понял, вам нужно защититься от ситуации, когда пользователь ввёл данные в форму, а записать объект не удаётся, т.к. объект уже изменен. Я правильно понял? От этого вам не защититься ни как. Т.к. даже если пользователь открыл форму, а в этот момент вы запустили обработку по объектам, объект будет доступен для изменения.
---
Мне необходима защита от того, что два пользователя вносят изменения в один документ и у них споры возникают. Необходимо только одному. В большинстве случае отрабатывает уже существующее Заблокировать Разблокировать. Но бывает что и нет,по непонятной причине.
---
По какой причине я уже сказал почему. Копайте в этом направлении. На худой конец фиксируйте всякое открытие формы в специальном регистре, с установкой полной блокировки.
---
То есть имеет смысл после Разблокировать (); Написать снова объект.Заблокировать? Если ставить целью усиление "аромата" этого кода, то безусловно имеет смысл.