Выполняет блокировку объекта от изменения другими режимами или пользователями.
Синтаксис
Заблокировать()Полное описание, параметры и ограничения
ПланВидовРасчетаОбъект.<Имя плана видов расчета>.Заблокировать (ChartOfCalculationTypesObject.<Chart of calculation types name>.Lock)
ПланВидовРасчетаОбъект.<Имя плана видов расчета> (ChartOfCalculationTypesObject.<Chart of calculation types name>)
Заблокировать (Lock)
Доступен, начиная с версии 8.0.
Синтаксис:
Заблокировать()
Описание:
Выполняет блокировку объекта от изменения другими режимами или пользователями.
Доступность:
Сервер, толстый клиент, внешнее соединение.
Использование в версии:
Доступен, начиная с версии 8.0.
Методическая информация
Практические примеры
Вид расчёта B: блокировка своего экземпляра без расчёта и записи
На сохранённой собственной премии B показываем приобретение и снятие блокировки, отличая признак экземпляра от блокировки записи другими пользователями.
Где и как запускать
Полный обычный клиентский общий модуль УчебныеМенеджерыРасчетов85 → УчебныеВиды85. Собственный Пульт отдельно ниже; не выполнялся.
Подготовка
Создайте НОВУЮ отдельную файловую базу 8.5.1.1343: имя конфигурации УчебныеМенеджерыРасчетов85, совместимость НеИспользовать, обычное приложение и толстый клиент. Не используйте рабочие ЗУП/КА/УТ/УНФ/БП. Здесь код, стенд и формы не выполнялись: runtimeVerifiedScenarios=0.
План видов расчёта Уч85Начисления: Код Строка(10), переменная длина, наименование 100, уникальность кода включена. ИспользованиеПериодаДействия=Да, ЗависимостьОтВидовРасчета=ПоПериодуДействия, в базовых планах только сам Уч85Начисления. Собственный реквизит Уч85Ключ Строка(8), Индексировать. Нет предопределённых элементов, общих реквизитов, разделителей, регистров расчёта или расчётных алгоритмов. Модули пустые.
В стандартном списке своего плана вручную создайте ровно три обычных вида: A — код 10, имя Учебный оклад, ключ A, ПериодДействияБазовый=Истина; B — код 20, имя Учебная премия, ключ B, ПериодДействияБазовый=Ложь; C — код 30, имя Учебное отсутствие, ключ C, ПериодДействияБазовый=Ложь. Все без пометки удаления и не предопределённые.
У B вручную заполните три стандартные таблицы: БазовыеВидыРасчета содержит только ссылку A; ВедущиеВидыРасчета только A; ВытесняющиеВидыРасчета только C. У A/C все три таблицы пустые. Сохраните только эту собственную подготовку. Это технический граф связей, не утверждённая методика начисления зарплаты.
Общий модуль УчебныеВиды85: неглобальный, Клиент (обычное приложение)=Да, Сервер=Нет, Привилегированный=Нет, другие клиентские флаги=Нет. Вставляйте полный модуль одного выбранного урока целиком, не внутрь обработчика и не все варианты одновременно.
Создайте собственную обработку УчебныеВиды85 с обычной основной формой Пульт. Кнопка Выполнить, действие ВыполнитьНажатие; отдельный полный модуль формы приведён ниже. F7 и обновление только своего стенда, запуск Пульта в толстом клиенте.
Для этого варианта одна сессия своего стенда, все модули планов пустые. Общий модуль выполняет только чтение A/B/C, локальную проверку независимости и приобретение/снятие блокировки B. Рабочие базы и другие пользователи не участвуют. Приобретение блокировки — реальный будущий эффект, но здесь 1С не запускалась.
Процедура ВыполнитьПример() Экспорт
ПроверитьСвойКонтекст();
Свои = ПолучитьСвоиВиды();
Премия = Свои.B.ПолучитьОбъект();
Если Премия = Неопределено Тогда
ВызватьИсключение "Собственная премия B исчезла";
КонецЕсли;
Если ТипЗнч(Премия) <> Тип("ПланВидовРасчетаОбъект.Уч85Начисления")
Или Премия.ЭтоНовый() Или Премия.Ссылка <> Свои.B Тогда
ВызватьИсключение "Нужен сохранённый конкретный объект собственного вида B";
КонецЕсли;
Второй = Свои.B.ПолучитьОбъект();
Если Второй = Неопределено Тогда
ВызватьИсключение "Собственная запись исчезла до проверки независимости";
КонецЕсли;
ИсходноеИмя = Премия.Наименование;
Второй.Наименование = "Второй локальный экземпляр премии";
Если Премия.Наименование <> ИсходноеИмя Тогда
ВызватьИсключение "Нужны два независимых экземпляра своего вида";
КонецЕсли;
Второй.Прочитать();
Если Второй.Наименование <> ИсходноеИмя Или Премия.Заблокирован() Или Второй.Заблокирован() Тогда
ВызватьИсключение "Нужны два исходно незаблокированных собственных экземпляра";
КонецЕсли;
СвояБлокировка = Ложь;
Попытка
Премия.Заблокировать();
СвояБлокировка = Истина;
Если Не Премия.Заблокирован() Или Второй.Заблокирован() Тогда
ВызватьИсключение "Признак должен относиться к блокировке данного объекта встроенного языка";
КонецЕсли;
Сообщить("Первый экземпляр B владеет своей блокировкой; второй признак не показывает общую занятость записи.");
Исключение
Если СвояБлокировка Тогда
Премия.Разблокировать();
КонецЕсли;
ВызватьИсключение;
КонецПопытки;
Премия.Разблокировать();
Если Премия.Заблокирован() Тогда
ВызватьИсключение "Снятие собственной блокировки не подтвердилось";
КонецЕсли;
ПолучитьСвоиВиды();
Сообщить("В собственном плане прежние A/B/C и реальные связи B с A/A/C. Запись, расчёт, удаление и пометка не выполнялись.");
КонецПроцедуры
Процедура ПроверитьСвойКонтекст()
Если Метаданные.РежимСовместимости <> Метаданные.СвойстваОбъектов.РежимСовместимости.НеИспользовать Тогда
ВызватьИсключение "Нужен собственный стенд УчебныеМенеджерыРасчетов85 платформы 8.5.1.1343";
КонецЕсли;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Учебный вывод не должен выполняться внутри чужой транзакции";
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьСвойОсновнойПлан()
Описание = Метаданные.ПланыВидовРасчета.Найти("Уч85Начисления");
Если Описание = Неопределено Тогда
ВызватьИсключение "Создайте собственный план Уч85Начисления";
КонецЕсли;
Если Описание.ТипКода <> Метаданные.СвойстваОбъектов.ТипКодаПланаВидовРасчета.Строка
Или Описание.ДлинаКода <> 10 Или Описание.ДлинаНаименования <> 100
Или Не Описание.ИспользованиеПериодаДействия
Или Описание.ЗависимостьОтВидовРасчета <> Метаданные.СвойстваОбъектов.ИспользованиеБазыПланаВидовРасчета.ПоПериодуДействия Тогда
ВызватьИсключение "Настройки учебного плана не соответствуют подготовке";
КонецЕсли;
Если Описание.БазовыеВидыРасчета.Количество() <> 1
Или Не Описание.БазовыеВидыРасчета.Содержит(Описание) Тогда
ВызватьИсключение "Выберите только собственный план как базовый";
КонецЕсли;
КонецПроцедуры
Функция ПолучитьСвоиВиды()
ПроверитьСвойОсновнойПлан();
Менеджер = ПланыВидовРасчета.Уч85Начисления;
A = Менеджер.НайтиПоРеквизиту("Уч85Ключ", "A");
B = Менеджер.НайтиПоРеквизиту("Уч85Ключ", "B");
C = Менеджер.НайтиПоРеквизиту("Уч85Ключ", "C");
Если A.Пустая() Или B.Пустая() Или C.Пустая() Или A = B Или A = C Или B = C Тогда
ВызватьИсключение "Подготовьте три разные реальные ссылки своего основного плана";
КонецЕсли;
Коды = Новый Структура("A,B,C", "10", "20", "30");
Имена = Новый Структура("A,B,C", "Учебный оклад", "Учебная премия", "Учебное отсутствие");
Свои = Новый Структура("Менеджер,A,B,C,Коды,Имена", Менеджер, A, B, C, Коды, Имена);
Ключи = Новый Массив;
Выборка = Менеджер.Выбрать(, "Код Возр");
Пока Выборка.Следующий() Цикл
Ключ = Выборка.Уч85Ключ;
ОжидаемыйКод = Неопределено;
ОжидаемоеИмя = Неопределено;
Если Не Коды.Свойство(Ключ, ОжидаемыйКод) Или Не Имена.Свойство(Ключ, ОжидаемоеИмя) Тогда
ВызватьИсключение "В основной выборке есть лишний учебный вид";
КонецЕсли;
Если Выборка.Код <> ОжидаемыйКод Или Выборка.Наименование <> ОжидаемоеИмя
Или Выборка.ПометкаУдаления Или Выборка.Предопределенный Или Выборка.ИмяПредопределенныхДанных <> ""
Или Выборка.Ссылка <> Свои[Ключ] Тогда
ВызватьИсключение "Поля собственного вида не совпали с подготовкой";
КонецЕсли;
ПроверитьСвоиСвязи(Выборка, Ключ, Свои);
Ключи.Добавить(Ключ);
КонецЦикла;
Если СтрСоединить(Ключи, ",") <> "A,B,C" Тогда
ВызватьИсключение "Основной план должен содержать ровно A,B,C в порядке кода";
КонецЕсли;
Возврат Свои;
КонецФункции
Процедура ПроверитьСвоиСвязи(Выборка, Ключ, Свои)
Если ТипЗнч(Выборка.ПериодДействияБазовый) <> Тип("Булево") Или Выборка.ПериодДействияБазовый <> (Ключ = "A") Тогда
ВызватьИсключение "Только собственный A имеет подготовленный признак базового периода";
КонецЕсли;
Если Ключ = "B" Тогда
Если Выборка.БазовыеВидыРасчета.Количество() <> 1 Или Выборка.ВедущиеВидыРасчета.Количество() <> 1
Или Выборка.ВытесняющиеВидыРасчета.Количество() <> 1 Тогда
ВызватьИсключение "У B нужны три реальные подготовленные строки зависимостей";
КонецЕсли;
Если Выборка.БазовыеВидыРасчета.Получить(0).ВидРасчета <> Свои.A
Или Выборка.ВедущиеВидыРасчета.Получить(0).ВидРасчета <> Свои.A
Или Выборка.ВытесняющиеВидыРасчета.Получить(0).ВидРасчета <> Свои.C Тогда
ВызватьИсключение "У B базовый/ведущий A и вытесняющий C, не плановые случайные ссылки";
КонецЕсли;
Иначе
Если Выборка.БазовыеВидыРасчета.Количество() <> 0 Или Выборка.ВедущиеВидыРасчета.Количество() <> 0
Или Выборка.ВытесняющиеВидыРасчета.Количество() <> 0 Тогда
ВызватьИсключение "У A/C таблицы зависимостей должны быть пустыми";
КонецЕсли;
КонецЕсли;
КонецПроцедурыУчебныеВиды85.Пульт
УчебныеМенеджерыРасчетов85 → Обработки → УчебныеВиды85 → Пульт → Модуль
Полный модуль собственной обычной формы; не выполнялся.
Процедура ВыполнитьНажатие(Кнопка)
УчебныеВиды85.ВыполнитьПример();
КонецПроцедурыРазбор по шагам
Переиспользуем полную подготовку своего плана Уч85Начисления и проверяющий модуль трёх сохранённых A/B/C. У B реальные базовый A, ведущий A, вытесняющий C; случайные ссылки не создаются.
ПолучитьОбъект даёт свой конкретный сохранённый B; проверяются nullable результат, прикладной тип, ЭтоНовый и равенство ссылки. Не принимаем неизвестный исходный объект.
У второго экземпляра изменяем имя только в памяти и проверяем, что первый не изменился. Второй перечитывается до блокировки. Если независимость не подтвердилась, блокировку не берём.
Заблокирован относится к конкретному объекту встроенного языка. False второго экземпляра не означает, что запись вообще свободна для других пользователей.
После успешного Заблокировать ставим флаг владения. При ошибке снимаем только приобретённую нами блокировку и передаём ошибку; на успешном пути снимаем и перепроверяем её отдельно.
В конце снова читаем собственные A/B/C и их связи. Здесь нет запуска алгоритма начисления, Записать, пометки удаления, изменения зависимостей или настоящего сетевого обмена.
Как проверить результат
Будущий тест: F7 и собственный Пульт толстого клиента. До и после ровно A/B/C с прежними именами/кодами/связями.
Внутри собственного опыта первый признак True, второй False; после снятия первого False. Не использовать эти значения как проверку всей базы на чужие блокировки.
Подготовить условия единственной сессии заранее; в рабочей базе конфликт блокировок не воспроизводить. Если приобретение/снятие завершилось ошибкой, опыт не объявлять успешным.
Ожидаемый результат
Будущий опыт приобретает и снимает только собственную блокировку экземпляра B, сохраняя исходные определения и зависимости видов расчёта. Runtime-проверка не выполнялась.
На что обратить внимание
Заблокирован не диагностирует блокировку записи вообще. Второй конкурентный захват здесь не выполняется.
Возврат ошибки после попытки освобождения не доказывает, что освобождение удалось: ошибка Разблокировать требует внимания и не считается успешным завершением.
Этот технический опыт не вычисляет зарплату и не создаёт движения регистра расчёта. Блокировки применяются только к собственному учебному объекту.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.