К статье
Практический материал

Администрирование · 13 мин

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

Разбираем способы блокировки регистра сведений в 1С: программные блокировки, управляемые блокировки, блокировка от изменений через даты запрета и подписки на события.

Заблокировать регистр сведений в 1С может понадобиться в нескольких ситуациях: при массовой загрузке данных, чтобы исключить конкурентную запись; при регламентных операциях, когда регистр временно не должен меняться; при расследовании ошибок, когда нужно «заморозить» данные для анализа. В зависимости от цели применяются разные механизмы — от программных блокировок в коде до даты запрета редактирования.

Важно понимать разницу между видами блокировок. Автоматические блокировки СУБД возникают сами при записи и снимаются при завершении транзакции — ими управлять напрямую не нужно. Управляемые блокировки разработчик накладывает явно через объект БлокировкаДанных. Административные ограничения (даты запрета, права, подписки на события) не блокируют таблицу на уровне СУБД, а запрещают изменения на уровне логики платформы.

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

Какие виды блокировок применимы к регистру сведений

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

Практически используются четыре подхода:

  • Управляемая блокировка — явная блокировка диапазона записей или всего регистра в коде, действует до конца транзакции.
  • Дата запрета редактирования — штатный механизм БСП, запрещает изменение данных до указанной даты.
  • Подписка на событие «ПередЗаписью» — программный отказ от записи по условию.
  • Настройка прав (RLS и роли) — ограничение доступа на уровне ролей, включая запрет записи для групп пользователей.

Управляемая блокировка — единственный способ, который реально «запирает» данные на уровне менеджера блокировок СУБД. Остальные варианты — логические запреты: они не создают блокировок в базе, но не дают изменить данные штатными средствами.

Программная блокировка через объект БлокировкаДанных

Основной инструмент — объект БлокировкаДанных. Создаётся элемент блокировки, указывается область «РегистрСведений.ИмяРегистра», при необходимости задаются значения измерений или диапазон, затем вызывается метод Заблокировать() внутри транзакции.

Пример блокировки всего регистра сведений «КурсыВалют» перед массовой загрузкой:

НачатьТранзакцию();

Попытка

Блокировка = Новый БлокировкаДанных;

ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.КурсыВалют");

ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;

Блокировка.Заблокировать();

// ... запись данных в регистр ...

ЗафиксироватьТранзакцию();

Исключение

ОтменитьТранзакцию();

ВызватьИсключение ОписаниеОшибки();

КонецПопытки;

Если блокировать весь регистр не нужно, ограничьте область по измерениям — это снизит вероятность конфликтов с другими сеансами:

ЭлементБлокировки.УстановитьЗначение("Валюта", ВалютаДоллар);

Для диапазона значений используется свойство ИсточникДанных элемента блокировки — туда передаётся таблица значений или результат запроса, а соответствие полей задаётся через ИспользоватьИзИсточникаДанных(). Это актуально, когда блокируется набор записей по списку контрагентов, номенклатуры или периодов.

Порядок установки управляемой блокировки
  1. 1
    Откройте транзакцию через НачатьТранзакцию()
  2. 2
    Создайте объект БлокировкаДанных и добавьте элемент с областью РегистрСведений.<Имя>
  3. 3
    Установите режим Исключительный или Разделяемый
  4. 4
    При необходимости ограничьте блокировку значениями измерений
  5. 5
    Вызовите Заблокировать(), выполните запись, зафиксируйте транзакцию
  6. 6
    В ветке исключения обязательно выполните ОтменитьТранзакцию()

Разделяемый и исключительный режимы: что выбрать

Режим Исключительный запрещает другим сеансам и читать (в режиме управляемых блокировок — накладывать любые блокировки), и писать заблокированные данные. Он нужен, когда вы собираетесь изменять записи и должны гарантировать, что никто параллельно их не прочитает для записи. Именно этот режим применяется при загрузках и пересчётах.

Режим Разделяемый запрещает запись, но позволяет другим сеансам читать данные и накладывать свои разделяемые блокировки. Он подходит, когда нужно гарантировать неизменность данных на время чтения — например, при формировании отчёта, который не должен видеть «подвисшие» промежуточные состояния.

Типичная ошибка — всегда ставить исключительный режим «на всякий случай». На больших регистрах это приводит к взаимоблокировкам и тайм-аутам у пользователей. Если задача — только чтение с гарантией целостности, используйте разделяемый режим.

Сравнение режимов блокировки

Исключительный

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

Разделяемый

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

Без блокировки (только транзакция)

Автоматические блокировки СУБД при записи. Достаточно для одиночных операций, но не защищает от чтения устаревших данных перед записью.

Блокировка регистра от изменений пользователями

Если цель — не координация параллельных сеансов, а запрет редактирования данных, программная блокировка не подходит: она живёт только внутри транзакции. Здесь нужны механизмы запрета.

В конфигурациях на Библиотеке стандартных подсистем (УТ, ERP, БП, ЗУП) есть «Даты запрета изменения данных» (Администрирование → Поддержка и обслуживание → Регламентные операции, либо раздел настройки прав). Установленная дата запрещает изменение данных прошлых периодов всем или выбранным пользователям. Для непериодических регистров сведений дата запрета применяется по дате объекта-источника, поэтому для независимых регистров механизм может не сработать — проверьте на копии базы.

Универсальный вариант — подписка на событие ПередЗаписью набора записей регистра. В обработчике проверяется условие (роль пользователя, «технологический» признак сеанса, параметр) и при необходимости вызывается отказ:

Процедура ЗапретЗаписиРегистраПередЗаписью(Источник, Отказ, Замещение) Экспорт

Если Не ПараметрыСеанса.РазрешенаЗаписьРегистра Тогда

Отказ = Истина;

ВызватьИсключение "Запись в регистр временно запрещена администратором";

КонецЕсли;

КонецПроцедуры;

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

Блокировка при обменах и фоновых заданиях

Частая практическая задача — не дать планам обмена или регламентным заданиям писать в регистр на время регламентных работ. Здесь программная блокировка бессильна: она снимется вместе с вашей транзакцией, а обмен придёт позже.

Рабочие варианты:

  • Отключить соответствующие регламентные задания в консоли заданий или через РегламентныеЗадания.НайтиПоУникальномуИдентификатору() с установкой Использование = Ложь.
  • Установить константу-признак «Идёт регламентная операция» и проверять её в подписке ПередЗаписью — обмен получит отказ и отложит пакет.
  • Для обменов через универсальный формат или EnterpriseData — заблокировать настройку синхронизации штатным признаком.

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

Проверка результата и диагностика конфликтов

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

Второй способ — технологический журнал. Включите сбор событий TLOCK, TDEADLOCK и TTIMEOUT в logcfg.xml и проанализируйте, какие блокировки накладываются, сколько держатся и кем. Это основной инструмент при поиске причин взаимоблокировок.

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

Контрольные точки

Как проверить результат

Параллельная запись в регистр
Норма

Второй сеанс получает ошибку конфликта или отказ с понятным текстом

Тревожный признак

Оба сеанса записывают данные без ошибок — блокировка не наложена

Технологический журнал (TLOCK)
Норма

Видны управляемые блокировки по области регистра с коротким временем удержания

Тревожный признак

Блокировок нет или они удерживаются минутами — риск взаимоблокировок

Запрет изменений для пользователя
Норма

При записи выводится заданное сообщение об отказе, данные не меняются

Тревожный признак

Запись проходит — подписка не срабатывает или дата запрета не настроена

Типичные ошибки и ограничения

Самая распространённая ошибка — вызов Заблокировать() вне транзакции. Платформа выдаст ошибку «Блокировка данных может быть установлена только в транзакции», либо блокировка будет снята немедленно. Всегда оборачивайте установку в НачатьТранзакцию() / ЗафиксироватьТранзакцию().

Вторая ошибка — блокировка по всему регистру там, где достаточно диапазона. На крупных базах это превращает любую загрузку в «стоп-кран» для всех пользователей, работающих с регистром. Задавайте значения измерений максимально узко.

Третья группа ошибок — ожидание от управляемой блокировки того, чего она не делает. Она не запрещает чтение в режиме разделяемой блокировки, не действует после завершения транзакции и не защищает от записи через прямые запросы к СУБД (что само по себе недопустимо). Для постоянных запретов используйте права, подписки и даты запрета.

Типичные ошибки
01
Вызов Заблокировать() вне транзакции — ошибка платформы или мгновенное снятие блокировки
02
Исключительная блокировка всего регистра без необходимости — массовые тайм-ауты у пользователей
03
Отсутствие ОтменитьТранзакцию() в обработчике исключения — висящие транзакции и блокировки
04
Ожидание, что блокировка действует после фиксации транзакции — для постоянного запрета нужны подписки или даты запрета
05
Игнорирование режима управления блокировками в свойствах конфигурации — код не работает в автоматическом режиме

Частые вопросы

Можно ли заблокировать регистр сведений навсегда, а не на время транзакции?

На уровне СУБД — нет, постоянных блокировок в 1С не существует. Для постоянного запрета изменений используйте подписку на событие ПередЗаписью с отказом, настройку прав (снятие права «Добавление» и «Изменение» у ролей) или дату запрета редактирования. Эти механизмы действуют постоянно, пока их не отключат.

Чем отличается блокировка регистра сведений от блокировки регистра накопления?

Технически — только именем области («РегистрСведений.Имя» вместо «РегистрНакопления.Имя»). Практическая разница в том, что у регистра накопления блокировку обычно накладывают по регистратору, а у независимого регистра сведений регистратора нет, поэтому диапазон задаётся значениями измерений.

Почему пользователи получают «Конфликт блокировок при выполнении транзакции»?

Один сеанс удерживает исключительную блокировку на записи регистра, а второй пытается записать или заблокировать те же данные. Причины — длинные транзакции, блокировка всего регистра вместо диапазона, параллельные фоновые задания. Анализируйте технологический журнал по событиям TLOCK и TTIMEOUT, сужайте область блокировки и сокращайте время транзакции.

Работает ли управляемая блокировка в файловой базе?

Файловая база работает в режиме автоматических блокировок, и вызов Заблокировать() приведёт к ошибке, если режим конфигурации — «Автоматический». Кроме того, в файловом режиме вся база монопольно блокируется при записи. Управляемые блокировки имеют смысл только в клиент-серверном варианте.

Как заблокировать регистр только для обмена, но не для пользователей?

Установите константу-признак или параметр сеанса, различающий контекст. В подписке ПередЗаписью проверяйте, выполняется ли запись в рамках обмена (например, по имени пользователя узла обмена или по признаку Загрузка = Истина у набора записей), и отказывайте только в этом случае. Свойство ОбменДанными.Загрузка обходит бизнес-логику, поэтому проверять его нужно аккуратно.

Что делать, если после аварии блокировка «зависла»?

Управляемые блокировки снимаются автоматически при завершении сеанса или транзакции — «зависших» управляемых блокировок не бывает. Если сеанс завис, завершите его через консоль кластера серверов 1С. Если «завис» логический запрет (константа-признак не сброшена), сбросьте её вручную через режим предприятия или консоль кода.

Итог

Что важно запомнить

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