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

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

Как заблокировать таблицу в 1С: полное руководство

Как заблокировать таблицу в 1С: управляемые и автоматические блокировки, объектный метод Заблокировать(), блокировка данных в запросе, типичные ошибки и проверка результата.

Блокировка таблицы в 1С — это механизм, который не даёт двум пользователям или фоновым процессам одновременно изменять одни и те же данные. Без блокировок при параллельной работе возможны «грязные» чтения, потерянные обновления и расхождения итогов по регистрам. Понимание того, как и чем блокировать таблицу, нужно и разработчику, и администратору базы.

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

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

Как устроены блокировки в 1С и какие режимы существуют

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

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

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

Блокировка всей таблицы через БлокировкаДанных

Основной инструмент явной блокировки — объект встроенного языка БлокировкаДанных. Чтобы заблокировать таблицу целиком, нужно добавить элемент блокировки, указать пространство блокировок (имя таблицы в метаданных) и не задавать отбор по полям — тогда блокируется вся таблица.

Типовой код выглядит так:

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

ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиТоваров");

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

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

Критически важный момент: управляемая блокировка устанавливается только внутри транзакции. Если вызвать Блокировка.Заблокировать() вне транзакции, блокировка будет немедленно снята и не защитит данные. Правильная обёртка выглядит так: НачатьТранзакцию() — установка блокировки — чтение или запись — ЗафиксироватьТранзакцию().

Если блокировать всю таблицу не обязательно, лучше сузить область: задать отбор по измерениям или реквизитам через ЭлементБлокировки.УстановитьЗначение("Склад", Склад) или диапазон значений. Это снижает вероятность взаимоблокировок и уменьшает время ожидания других сеансов.

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

Блокировка отдельного объекта методом Заблокировать()

Когда нужно заблокировать не таблицу целиком, а конкретную запись — документ, элемент справочника, запись регистра сведений, — удобнее объектный метод Заблокировать(). Он вызывается у объекта, полученного через ПолучитьОбъект(), и устанавливает блокировку на эту ссылку в базе данных.

Пример: ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект(); ДокОбъект.Заблокировать();. После этого другой сеанс, попытавшийся заблокировать тот же объект, получит исключение «Конфликт блокировок при выполнении транзакции» или сообщение о том, что объект редактируется другим пользователем.

Метод Заблокировать() не требует открытой транзакции — блокировка удерживается до вызова Разблокировать() или до завершения сеанса. Это удобно для интерактивных сценариев, но опасно: если сеанс «завис», объект останется заблокированным до принудительного завершения сеанса администратором.

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

Блокировка данных при чтении запросом

Частая задача — прочитать данные так, чтобы никто не успел их изменить до конца транзакции, например при расчёте остатков перед списанием. Для этого в языке запросов служит конструкция ДЛЯ ИЗМЕНЕНИЯ, которую добавляют в конец текста запроса с указанием таблиц.

Пример: ВЫБРАТЬ ... ИЗ РегистрНакопления.ОстаткиТоваров.Остатки(...) КАК Остатки ДЛЯ ИЗМЕНЕНИЯ РегистрНакопления.ОстаткиТоваров. Запрос установит разделяемую или исключительную блокировку (в зависимости от режима СУБД и настроек) на читаемые записи до конца транзакции.

Альтернатива — установить управляемую блокировку через БлокировкаДанных перед выполнением запроса, а запрос писать без ДЛЯ ИЗМЕНЕНИЯ. В управляемом режиме блокировок именно этот подход считается основным, потому что он даёт более предсказуемую гранулярность и меньше зависит от поведения конкретной СУБД.

Учтите: в файловом варианте базы любая блокировка фактически накладывается на таблицу целиком, а не на отдельные записи. Это ограничение файловой СУБД, встроенной в платформу, и обойти его нельзя — только переходом на клиент-серверный вариант с MS SQL, PostgreSQL или Oracle.

Способы блокировки и когда их применять

БлокировкаДанных

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

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

Для одиночных объектов и интерактивных сценариев; удерживается сеансом, риск «вечных» блокировок при зависании

ДЛЯ ИЗМЕНЕНИЯ в запросе

Для защиты читаемых данных до конца транзакции; поведение зависит от СУБД

Автоматический режим

Когда конфигурация простая и параллельность низкая; не требует кода, но менее предсказуем

Административная блокировка базы и соединений

Иногда под «заблокировать таблицу» понимают другое — запретить пользователям работу с базой на время обновления или регламентных операций. Для этого используется блокировка сеансов, а не блокировка данных. В типовых конфигурациях на БСП она включается в разделе «Администрирование — Обслуживание — Блокировка работы пользователей».

Для клиент-серверной базы блокировку соединений можно задать и через консоль кластера серверов 1С: свойства информационной базы, параметр «Блокировка начала сеансов включена». Там же задаётся сообщение пользователям и код разрешения для входа администратора.

Эта блокировка не защищает отдельные таблицы — она просто не пускает новые сеансы и по расписанию завершает существующие. Для защиты конкретных данных внутри рабочей базы она не подходит.

Диагностика: как понять, что таблица заблокирована, и кто это сделал

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

Для поиска виновника в клиент-серверном варианте откройте консоль кластера: раздел «Сеансы» покажет активные сеансы и время их работы, а в MS SQL данные о блокировках дают представления sys.dm_tran_locks и системный отчёт по блокировкам. В файловом варианте доступен только список активных пользователей («Администрирование — Активные пользователи»), детализация по таблицам там невозможна.

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

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

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

Код блокировки выполнен
Норма

Метод Заблокировать() отработал без исключения, транзакция открыта

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

Исключение «Конфликт блокировок» — данные уже заняты другим сеансом

Повторный захват из второго сеанса
Норма

Второй сеанс получает ошибку ожидания блокировки

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

Второй сеанс свободно изменяет данные — блокировка не установлена или снята

После фиксации транзакции
Норма

Другие сеансы снова могут работать с таблицей

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

Блокировка «висит» — проверьте незавершённые транзакции и зависшие сеансы

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

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

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

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

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

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

Таблицу в 1С блокируют через БлокировкаДанных внутри транзакции, отдельный объект — методом Заблокировать(), данные при чтении — конструкцией ДЛЯ ИЗМЕНЕНИЯ. Блокируйте минимально необходимый объём, всегда проверяйте открытие транзакции и помните: постоянного запрета изменений блокировки не дают — для этого есть даты запрета и права.

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

Можно ли заблокировать таблицу в 1С без программирования?

Штатного интерфейсного способа заблокировать конкретную таблицу нет. Администратор может заблокировать всю базу через «Блокировку работы пользователей» или консоль кластера, а запрет изменения данных за прошлые периоды настраивается через даты запрета редактирования. Блокировка отдельной таблицы возможна только программно.

Чем управляемые блокировки лучше автоматических?

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

Что делать, если пользователь получает ошибку «Конфликт блокировки»?

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

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

Нет. В файловом варианте платформа блокирует таблицу целиком, даже если в коде указан отбор по конкретным записям. Гранулярные блокировки уровня записей доступны только в клиент-серверном варианте с внешней СУБД.

Как запретить изменение документов за прошлый период?

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

Почему блокировка, установленная в коде, не срабатывает?

Чаще всего причина в том, что Блокировка.Заблокировать() вызвана вне транзакции — блокировка снимается немедленно. Также проверьте режим управления блокировкой в свойствах конфигурации: в автоматическом режиме управляемые блокировки игнорируются. Убедитесь, что имя пространства блокировок указано точно как в метаданных, например «РегистрНакопления.ОстаткиТоваров».