1с как заблокировать запись регистра сведений

Обновлено: 06.07.2024

admin

18 thoughts on “ Управляемый режим блокировки данных (1С: V8: Программисту) ”

А для чего внешний цикл вокруг попытки, если он в обоих случаях прерывается без продолжения?

При этом текст вызываемой функции с проверкой на взаимоблокировки примерно такой:

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

Поэтому у меня есть несколько нубских вопросов.

По поводу функции ахОшибкаБлокировки() три вопроса:

2. Вместо spin-блокировки в 1С другой возможности подождать нет?
Какой-нибудь sleep(1000)?

3. Зачем тут используется СлучайноеЧисло()?

По поводу исходного поста, по-моему:

1. Внешний цикл не нужнен.

2. Нужно снять блокировки после фиксации транзакции.

Код в 1С не проверялся. Если я в чем-то ошибся, поправьте меня.

Интересно, что будет написано в английской версии вместо
«Превышено максимальное время ожидания предоставления блокировки»
и «Неустранимый конфликт блокировок»?

Написано будет, конечно, не на русском. Чтобы посмотреть, что именно будет написано, нужно поэкспериментировать в английской версии с блокировками и прочитать то, что предприятие выдаст в ответ.

2. Вместо spin-блокировки в 1С другой возможности подождать нет?
Какой-нибудь sleep(1000)?

3. Зачем тут используется СлучайноеЧисло()?

Или придумать другую, более надежную схему.

Кстати, спасибо за Ваши примеры. Посмотрим.

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

Блокировка снимается автоматически:
«Если этот метод [метод Заблокировать() объекта БлокировкаДанных] выполняется в транзакции (явной или неявной), блокировки устанавливаются, и при окончании транзакции будут сняты автоматически.» (1-361 в 8.1, 1-501 в 8.2)

Меня ввело в заблуждение указание, что:
«Блокировки объектов, установленные в течение транзакции, сохраняются при фиксации транзакции и снимаются при откате транзакции.» (1-354 в 8.1)

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

Не совсем так. В книге все верно. Речь в цитируемом Вами месте (где Вы усмотрели ошибку) идет о пессимистической объектной блокировке, осуществляемой командой вида

Где ТекОбъект – это объект, например, справочника «Номенклатура», предварительно полученный, например, таким выражением:

Огромное спасибо за разъяснения по поводу блокировок объектов. У меня теперь в мозгу порядок наступил.

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

Поэтому сразу скажу, что у меня такая система:
1С 8.2.12.80 на PostgreSQL 8.3.3-2.1C.
(комп = Pentium Core 2 Duo 3.0 GHz, 2 Gb RAM, WinXP).

Еще раз спасибо за разъяснения про блокировки.

1C 8.1, 15 релиз платформы, SQL-ная
64-разрядная Windows на сервере
загруженность процессора в % сказать не могу

> соединение, у которого первым оказалось превышение счетчика, выводится из цикла

Попробую объяснить свою точку зрения на то, почему в вашем случае 1000 итераций пустого цикла помогает разрешить ситуацию.

Рассмотрим такой сценарий:
Пусть у нас есть таблица с двумя записями . Цифрой буду отмечать номер клиента, блокировавшего данные:


1. Клиент1 запросил блокировку и заблокировал запись A.

2. Клиент2 запросил блокировку и заблокировал запись Б.

3. Клиент3 запросил блокировку на А и Б, и теперь ждет.

4. Клиент1 закончил обработку и снял блокировку с A. Клиент3 ждет.

5. Клиент4 запросил блокировку и заблокировал запись A. Клиент3 ждет.

6. Клиент2 закончил обработку и снял блокировку с Б. Клиент3 ждет.

7. Клиент5 запросил блокировку и заблокировал запись Б. Клиент3 ждет.

и т.д.

Получается, что Клиент3 так и не получил своей блокировки на обе записи сразу, хотя по-очереди они были свободны.
Задача решится, если, например, шаги 5. и 6. поменять местами. Тогда Клиент3 сможет заблокировать обе записи
и выполнить свою работу.

1) Рассмотрим первый сценарий, где ваш цикл мог бы сработать.

Первый сценарий заключается в следующем: для того, чтобы как-то перемешать требования блокировок от разных сеансов,
необходимо передать управление другому потоку, т.е. цикл должен случайно завершить хотя бы текущий квант
и управление передастся другому потоку.

Очевидно, что количества в 1000 не достаточно, чтобы гарантированно выскочить из кванта.
Поэтому этот сценарий скорее всего не срабатывает.

2) По всей вероятности, в перемешивании сеансов главную роль играет многопроцессорность.
Ведь при примерно одновременном начале исполнения двух потоков такая легкая случайная сдвижка
будет достаточно влиять на пару сеансов (если два ядра).

В этом сценарии, если нужно перемешивать три сеанса, то нужно уже три ядра, и т.д.

Можно выделить недостатки обоих сценариев вообще и использования пустого цикла в частности:

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

Почему все-таки нужно отказываться от spin-блокировок?

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

Для тестирования, запишем бесконечный цикл (Пока Истина Цикл КонецЦикла;)
в любом серверном коде и запустим на выполнение.

С другой стороны, добавим в цикл вызов Sleep(1). Результаты тестирования следующие:

Таким образом, используя Sleep() вместо spin-блокировки, получаем уменьшение загруженности
процессора в ( 1539 / 2 ) * ( 100 / 12 ) = 6412,5 раз.

Мне такой результат понравился. А Вам?

И, наконец, решение проблемы взаимо-блокировок: нужно упорядочить запросы на блокировки данных.
То есть нужно выстроить их в очередь так, чтобы пока Клиент3 не выставил свои блокировки, Клиент4
не мог запросить блокировки для своей маленькой транзакции.
Такое решение полностью разрешит все конфликты и уменьшит нагрузку на базу данных.

А теперь вопрос: есть ли в 1С какой нибудь вариант организации очереди?

Спасибо за интереснейшие комментарии и обстоятельное изложение. Попробуем этот вариант.

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

Учусь на ошибках.

Если MTA, то второй сеанс будет ждать 5 секунд.
Если STA, то второй сеанс будет ждать 125 секунд: сначала дождется доступа к занятому STA-потоку,
а затем сам займет его на 5 секунд.

Проверка показала, что если блокировка не удалась, то вся транзакция помечается как ошибочная и продолжать
работу в этой транзакции нельзя – нужно ее откатить.
Соответственно, утверждение “1. Внешний цикл не нужнен.” также неверно.

Если рассматривать первый модуль таким, как он приведен изначально (в самом первом посте), не подразумевая другую обработку «Исключения», то внешний цикл там действительно лишний – ведь ни в случае фиксации, ни в случае отката транзакции, цикл не повторяется (см. на «Прервать» в «Исключении»).

PS Спасибо за комментарии по Sleep, очень интересно.

По поводу организации очереди блокировок.

В зависимости от ситуации, можно рассмотреть применение, например, таких трех вариантов:

1. Очередь на блокировке таблицы всеми транзакциями.

2. Очередь на блокировке таблицы крупными транзакциями (т.е. очередь только для крупных транзакций).

Можно использовать для разруливания конфликтов между крупными транзакциями, если их приходит несколько разом. Однако, если много мелких транзакций, то нет гарантии когда начнет выполнятся крупная транзакция, стоящая первой в очереди.

3. Очередь на блокировке с помощью объектов, не связанных с базой данных. Для сервера 1С на одном компьютере подходят, например, объекты ядра Windows (критические секции, мьютексы, события с автосбросом и т.д.).

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

Для себя я реализовал очередь блокировок на критической секции.

Очередь основана на том, что при вызове EnterCriticalSection() поток либо получает единоличный доступ к критической секции, либо ставится планировщиком потоков в FIFO-очередь без таймаута.
Поток, владеющий критической секцией, может освободить ее вызовом LeaveCriticalSection().
Поддерживается вложенность вызовов, т.е. если вызвать EnterCriticalSection() два раза подряд, то не произойдет самоблокировки, но увеличится счетчик, поэтому нужно также дважды вызвать LeaveCriticalSection() для освобождения критической секции.

Для реализации этой очереди необходим COM-объект, запускаемый в MTA (Multi-Thread Apartment) и предоставляющий критическую секцию и методы EnterCriticalSection() и LeaveCriticalSection().
Критическая секция должна быть глобальной для процесса rphost.exe, то есть единой для всех потоков сессий, обрабатываемых в этом процессе.

Также, стоит добавить в COM-объект внутренний счетчик глубины входов в критическую секцию для потока, а в деструктор добавить выход из критической секции нужное количество раз, если счетчик окажется не нулевым.
Это нужно на случай, если поток (программист 1С) по каким-то причинам забудет вызвать LeaveCriticalSection() после EnterCriticalSection(). Иначе снять занятость критической секции можно будет только перезапуском сервера 1С.

Плюсы очереди блокировок на критической секции:

1. Скорость работы самих критических секций намного выше, чем тех же блокировок таблицы.
В общем-то, скорость такой очереди упирается только в скорость установки блокировок нужных данных.

2. Параллельность выполнения последовательных независимых транзакций, начиная с шага, следующего за шагом установки блокировок.

Минусы указанной реализации:

1. Критические секции можно использовать только в рамках одного процесса rphost.exe.

Если у вас несколько процессов rphost.exe на одной машине, то вместо критических секций можно, например, использовать именованный мьютекс.

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

4. Нет параллельности обработки независимых транзакций, которые идут в очереди не последовательно.

Если есть работающая Транзакция1, блокирующая записи ,
в вершине очереди стоит Транзакция2, пытающаяся блокировать запись ,
а затем в очереди идет Транзакция3, которая будет работать с записью .

Транзакция2 будет ожидать снятия блокировки на запись из-за работы первой транзакцией.
А Транзакция3, которая могла бы быть обработана, будет ожидать в очереди, поскольку
Транзакция2 еще не выставила свои блокировки и не освободила очередь.

Если крупная транзакция занята тем, что ставит блокировку, то ее ждут все остальные в очереди.
При этом, если в диапазоне блокировок этой транзакции имеется блокировка строки, над которой какая-то мелкая транзакция будет работать еще долго, то и эта крупная и все остальные в очереди будут ожидать до таймаута блокировки на SQL-сервере.

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

Ответственное чтение данных

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

1. Общие рекомендации по использованию транзакций при чтении данных

Область применения (уточнение): управляемое приложение, обычное приложение.

1.1. Если чтение данных из информационной базы должно быть ответственным, следует производить такое чтение в транзакции с предварительной установкой управляемых блокировок. В общем случае, ответственным следует считать любое чтение, на основе результатов которого производятся какие-либо изменения в информационной базе или принимаются решения.
Например, ответственное чтение данных требуется в следующих случаях:

Чтение данных при проведении, для последующего формирования движений; Чтение данных для последующей целостной передачи в другую систему, например в программы типа «Клиент банк»;

Выполнение групповой обработки объектов, при реструктуризации данных в обработчиках отложенного и оперативного обновления ИБ (*)

* Примечание: перед модификацией ссылочных объектов, обычно, следует устанавливать на них пессимистичные объектные блокировки .

// 1. Прочитать регистр сведений
Запрос = Новый Запрос(
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ЗаметкиПоПредмету.КоличествоЗаметок КАК КоличествоЗаметок
|ИЗ
| РегистрСведений.ЗаметкиПоПредмету КАК ЗаметкиПоПредмету
|ГДЕ
| ЗаметкиПоПредмету.Предмет = &Предмет");
Запрос.УстановитьПараметр("Предмет", ПредметЗаметок);
Выборка = Запрос.Выполнить().Выбрать();

КоличествоЗаметок = 0;
Если Выборка.Следующий() Тогда
КоличествоЗаметок = Выборка.КоличествоЗаметок;
КонецЕсли;

// 2. Записать в регистр сведений
НаборЗаписей = РегистрыСведений.ЗаметкиПоПредмету.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Предмет.Установить(ПредметЗаметок);
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Предмет = ПредметЗаметок;
НоваяЗапись.КоличествоЗаметок = КоличествоЗаметок + 1;
НаборЗаписей.Записать();

// 1. Начать транзакцию для пакета из двух операций чтения и записи регистра
НачатьТранзакцию();

Попытка
// 2. Установить исключительную блокировку на интересующий диапазон записей регистра,
// для того чтобы гарантировать, что в момент записи количество заметок не изменилось с момента чтения в каком-либо другом сеансе.
БлокировкаДанных = Новый БлокировкаДанных;
ЭлементБлокировкиДанных = БлокировкаДанных.Добавить("РегистрСведений.ЗаметкиПоПредмету");
ЭлементБлокировкиДанных.УстановитьЗначение("Предмет", ПредметЗаметок);
ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
БлокировкаДанных.Заблокировать();

// 3. Прочитать регистр сведений
Запрос = Новый Запрос(
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ЗаметкиПоПредмету.КоличествоЗаметок КАК КоличествоЗаметок
|ИЗ
| РегистрСведений.ЗаметкиПоПредмету КАК ЗаметкиПоПредмету
|ГДЕ
| ЗаметкиПоПредмету.Предмет = &Предмет");
Запрос.УстановитьПараметр("Предмет", ПредметЗаметок);

КоличествоЗаметок = 0;
Если Выборка.Следующий() Тогда
КоличествоЗаметок = Выборка.КоличествоЗаметок;
КонецЕсли;

// 4. Записать в регистр сведений
НаборЗаписей = РегистрыСведений.ЗаметкиПоПредмету.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Предмет.Установить(ПредметЗаметок);
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Предмет = ПредметЗаметок;
НоваяЗапись.КоличествоЗаметок = КоличествоЗаметок + 1;
НаборЗаписей.Записать();

ЗафиксироватьТранзакцию();
Исключение
// 5. Если при установке блокировки возникла исключительная ситуация из-за того, что регистр уже заблокирован в другом сеансе (или по другим причинам),
// отменить транзакцию и записать сведения об ошибке в журнал регистрации.
ОтменитьТранзакцию();
ЗаписьЖурналаРегистрации(НСтр("ru = 'Заметки'", ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка. ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение;
КонецПопытки;

В некоторых случаях, ответственное чтение не требуется в силу решаемой прикладной задачи, например:

  • Получение данных динамическими списками;
  • Поиск данных;
  • Формирование большинства отчетов.

В некоторых случаях, ответственное чтение не требуется, так как конкурентная работа с данными маловероятна или полностью исключена, например:

Обращение к условно постоянной информации. Например, чтение константы ВалютаРегламентированногоУчета или обращение к учетной политике; Действия, которые гарантированно выполняются в монопольном режиме. Например, в процедурах обновления и первоначального заполнения данных информационной базы; Действия над данными, доступ к которым имеет только один пользователь, поэтому конкурентная работа с ними маловероятна или полностью исключена.
Например, персональные данные, хранящиеся в «разрезе» пользователей; Мобильное приложение, где конкурентная работа с данными маловероятна или полностью исключена.

1.2. В большинстве случаев, при выполнении чтения в обработчиках событий связанных с модификацией данных, весь код обработчика выполняется в рамках системной транзакции, которая открыта платформой, и явно открывать новую транзакцию не требуется.

Например, в системной транзакции выполняются обработчики модулей объектов и соответствующие им подписки на события:

Область применения (уточнение): управляемое приложение, обычное приложение.

2. Выбор: исключительная или разделяемая блокировка

2.1. Если в транзакции производится ответственное чтение данных с их последующим изменением, необходимо установить исключительную управляемую блокировку (до выполнения чтения). В противном случае возможно возникновение взаимоблокировки.

Пример установки исключительной блокировки (без открытия транзакции – в предположении, что ранее уже была открыта системная транзакция):

// 1. Установить исключительную блокировку для ответственного чтения объекта с целью его дальнейшего изменения
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("Справочник.Приказы");
ЭлементБлокировки.УстановитьЗначение("Ссылка", ПриказСсылка);
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный; // можно не указывать, т.к. по умолчанию Исключительный
Блокировка.Заблокировать();

// 2. Получить объект для его дальнейшей модификации
Объект = ПриказСсылка.ПолучитьОбъект();
Если Объект = Неопределено Тогда // объект может быть уже удален в других сеансах
Возврат;
КонецЕсли;

// 3. Выполнить блокировку объекта от изменения другими сеансами
ЗаблокироватьДанныеДляРедактирования(ПриказСсылка);

// 4. Записать измененный объект
Объект.Реквизит = .
Объект.Записать();

2.2. Если в транзакции производится ответственное чтение данных без их последующего изменения (например, для формирования движений), необходимо установить разделяемую блокировку на читаемые данные и исключительную блокировку на изменяемые данные.

Пример установки разделяемой блокировки (без открытия транзакции – в предположении, что ранее уже была открыта системная транзакция):

// 1. Установить разделяемую блокировку для ответственного чтения нескольких связанных объектов
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("Справочник.Приказы");
ЭлементБлокировки.УстановитьЗначение("Ссылка", ПриказСсылка);
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Разделяемый;
Блокировка.Заблокировать();

// 2. Прочитать первый объект - приказ
ПриказОбъект = ПриказСсылка.ПолучитьОбъект();

// 3. Прочитать второй объект – пользователя (автора приказа)
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("Справочник.Пользователи");
ЭлементБлокировки.УстановитьЗначение("Ссылка", ПриказОбъект.Автор);
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Разделяемый;
Блокировка.Заблокировать();

Особенности блокировок регистров при работе с 1С:Предприятием 8 в варианте клиент-сервер

Блокировки, которые использует 1С:Предприятие 8 в варианте клиент-сервер, при выполнении запросов в рамках транзакции отличаются от блокировок, устанавливаемых при работе в варианте файл-сервер.

Технологические особенности

В варианте файл-сервер используются блокировки на уровне таблиц базы данных, тогда как в варианте клиент-сервериспользуются блокировки на уровне записей таблиц базы данных, которые позволяют 1С:Предприятию 8 обеспечить большую параллельность (пропускную способность) в конкурентных режимах работы. При этом используется высокий уровень изоляции транзакций - SERIALIZABLE, который обеспечивает неизменность прочитанных в рамках транзакции данных. При этом, на данном уровне изоляции, не допускается не только модификация другими транзакциями прочитанных данных, но и добавление новых записей в диапазон данных, ограниченный условиями выполняемого запроса. Это обеспечивает высокую степень целостности и непротиворечивости обрабатываемых в рамках транзакции данных.

Однако при определенных условиях блокировки, устанавливаемые в этом режиме, могут приводить к снижению пропускной способности системы в многопользовательском режиме конкурентного ввода документов. Причиной этого является эксклюзивные блокировки таблиц базы данных, устанавливаемые Microsoft SQL Server, при работе в заданном режиме изоляции транзакций (SERIALIZABLE) для обеспечения целостности и непротиворечивости обрабатываемых в рамках транзакции данных. Переход от блокировок на уровне записи таблицы базы данных к табличным блокировкам чаще всего обуславливается отсутствием записей в некоторых таблицах базы данных, используемых в рамках транзакции. Для обеспечения целостности прочитанных в рамках транзакции данных, Microsoft SQL Server блокирует весь диапазон прочитанных данных, не допуская добавления, удаления и модификации данных в рамках этого диапазона. Ввиду отсутствия записей в таблице, она блокируется целиком на все время выполнения транзакции, что приводит к деградации пропускной способности системы. Причиной этого является механизм, реализованный в Microsoft SQL Server, для обеспечения используемого в 1С:Предприятии 8 уровня изоляции транзакций SERIALIZABLE.

Рекомендуется, для достижения максимальной пропускной способности 1С : Предприятия 8 в режиме клиент-сервер, учитывать эту особенность при написании процедуры проведения документа, и не задействовать в запросах таблицы, которые не используются, или предоставлять пользователям возможность управлять их использованием в запросах средствами конфигурации.

Пример

Рассмотрим этот эффект на примере работы с регистрами накопления 1С:Предприятия 8.

Имеется документ и связанные с ним два регистра накопления, в которых регистрируются движения этого документа. При проведении этого документа, в процедуре проведения, проверяются остатки по этим регистрам, и производится запись движений этого документа. В случае, если по каким-либо причинам, один из регистров не используется для записи движений в процессе проведения документа, таблица этого регистра будет пустой.
Однако, если в процессе проведения документа, по этому регистру выполняется проверка остатков с использованием конструкции языка запросов "ДЛЯ ИЗМЕНЕНИЯ", вся таблица этого регистра окажется заблокированной до окончания транзакции. Это приведет к невозможности проведения аналогичных документов другими пользователями до окончания выполнения процедуры проведения.

Следует учитывать, что при обновлении записи таблицы базы данных с использованием уровня изоляции транзакций SERIALIZABLE, в общем случае, могут быть заблокированы и соседние записи этой таблицы, находящиеся рядом в индексе. То есть, если существуют записи с идентификаторами 3 и 5 и делается попытка изменить запись с идентификатором 4, то, в общем случае, будут дополнительно заблокированы записи с идентификаторами 3 и 5. Записи с идентификаторами меньше 3 и больше 5 могут быть модифицированы.

Следует заметить, что тестирование параллельности на пустой базе данных непоказательно, поскольку вероятность блокировок в таких условиях существенно выше. Механизм генерации идентификаторов объектов базы данных устроен таким образом, чтобы минимизировать вероятность возникновения блокировок при работе с 1С:Предприятием 8.

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

  • во-первых, проверить, что данный объект не заблокирован в настоящий момент другим пользователем;
  • во-вторых, гарантирует, что другой пользователь не сможет изменить объект, пока не будут записаны изменения в текущем сеансе;
Внимание! Данное правило неприменимо при пакетной загрузке данных, когда требуется принятие изменений пакетом, а также при разрешении коллизий, возникающих при загрузке данных из другого источника, обладающего большим приоритетом

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

  • Используя метод Заблокировать() объекта метаданных ссылочного типа (Справочники, Документы и т.п.);
  • Используя метод ЗаблокироватьДанныеДляРедактирования() глобального контекста;

Давайте рассмотрим примеры работы с каждым из этих методов

Метод Заблокировать()

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

Недостатки: Метод доступен только в контексте сервера, толстого клиента или внешнего соединения

Метод ЗаблокироватьДанныеДляРедактирования()

Данный метод обладает большим спектром возможностей, чем предыдущий:

  • он умеет блокировать записи регистра сведений;
  • он умеет блокировать данные в контексте управляемых форм;
  • он умеет блокировать данные, если совпадает версия данных;

С учетом этого, перепишем предыдущий пример следующим образом:

В том случае, когда нам необходимо заблокировать некоторые данные на время открытия управляемой формы, можно поступить следующим образом:

Блокировка будет снята неявно при закрытии привязанной формы, либо при завершении сеанса пользователя, либо явно при вызове метода РазблокироватьДанныеДляРедактирования()

Читайте также: