Для ключа guide-book устанавливаем управляемую блокировку в короткой собственной транзакции. При успехе и ошибке завершаем только свою транзакцию.
Где и как запускать
Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.
Подготовка
Только собственная пустая УчебнаяКонфигурацияСинтаксиса. Создайте независимый регистр сведений УчебныеРезервы, периодичность В пределах секунды, измерение КлючРезерва типа Строка длиной 50 и ресурс Количество типа Число. Записи регистра для уроков не нужны.
В собственной учебной конфигурации задайте Режим управления блокировкой данных=Управляемый. Создайте серверный общий модуль УчебныеЗадачи и процедуру ВыполнитьПример() Экспорт; каждый код вставляйте в её тело отдельно.
Вызывайте из собственной учебной обработки вне уже открытой транзакции. Не проводите рабочие документы, не запускайте в КА2/УНФ/УТ и не меняйте их режим блокировок ради опыта.
Первый урок только создаёт описание. Остальные реально устанавливают краткую управляемую блокировку в собственной транзакции и затем отменяют её. Данные не записываются и не удаляются.
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Запускайте отдельно, вне чужой транзакции";
КонецЕсли;
Схема = Метаданные.РегистрыСведений.Найти("УчебныеРезервы");
Если Схема = Неопределено Тогда
ВызватьИсключение "Создайте собственный учебный регистр УчебныеРезервы";
КонецЕсли;
Если Схема.Измерения.Найти("КлючРезерва") = Неопределено Тогда
ВызватьИсключение "Нет измерения КлючРезерва";
КонецЕсли;
Блокировка = Новый БлокировкаДанных;
Элемент = Блокировка.Добавить("РегистрСведений.УчебныеРезервы");
Элемент.Режим = РежимБлокировкиДанных.Исключительный;
Элемент.УстановитьЗначение("КлючРезерва", "guide-book");
НачатьТранзакцию(РежимУправленияБлокировкойДанных.Управляемый);
Попытка
Блокировка.Заблокировать();
Сообщить("Собственная управляемая блокировка установлена; данные не записывались");
ОтменитьТранзакцию();
Исключение
Если ТранзакцияАктивна() Тогда
ОтменитьТранзакцию();
КонецЕсли;
ВызватьИсключение;
КонецПопытки;
Сообщить(Не ТранзакцияАктивна());Разбор по шагам
Предварительная проверка запрещает запуск внутри чужой транзакции. Иначе ОтменитьТранзакцию могла бы затронуть не только упражнение.
НачатьТранзакцию получает Управляемый. Этот аргумент не превращает автоматически уже существующую автоматическую транзакцию в управляемую.
Заблокировать вызывается после начала собственной транзакции. В рабочей задаче защищаемое чтение/проверка/запись должны находиться внутри неё, но здесь намеренно нет записи данных.
При успехе отменяем собственную транзакцию сразу. При исключении отменяем только если она ещё активна и повторно выбрасываем исходную ошибку.
Нет отдельного придуманного Разблокировать у БлокировкаДанных. Управляемые транзакционные блокировки связаны с жизнью транзакции; конкуренция двух сеансов здесь не проверена.
Как проверить результат
При разрешённых управляемых блокировках появляется сообщение об установке, затем Истина для отсутствия активной транзакции.
При отказе/конфликте передаётся реальная ошибка; собственная транзакция не должна оставаться активной. Записей в регистре не создаётся.
Ожидаемый результат
Показан полный краткий цикл управляемой блокировки без вмешательства в чужую транзакцию.
На что обратить внимание
Не держите транзакцию открытой на время диалогов, ожидания пользователя, HTTP или длительного расчёта.
Сообщение об установке не доказывает эффективность будущего алгоритма резервирования. Для него нужны конкурентные тесты двух сеансов.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.