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

Разработка и Конфигурация · 15 мин

Управляемые блокировки в 1С: принципы работы и настройка

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

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

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

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

Что такое блокировки и зачем они нужны

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

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

Режим блокировок задаётся в свойстве конфигурации «Режим управления блокировкой данных». Доступны три значения: «Автоматический», «Управляемый» и «Автоматический и управляемый». Третий вариант — переходный: для каждого объекта метаданных можно отдельно указать, в каком режиме он работает, что удобно при миграции старой конфигурации на управляемые блокировки.

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

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

КритерийАвтоматический режимУправляемый режим
Кто определяет блокировкиПлатформа автоматическиРазработчик в коде
ГранулярностьТаблицы и страницы данныхОтдельные записи и диапазоны
Параллелизм работыНизкий при большой нагрузкеВысокий
Требования к кодуМинимальныеНужно явно ставить блокировки
Требования к СУБДЛюбая поддерживаемаяРекомендуется MS SQL Server, PostgreSQL, Oracle с версионностью

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

Сравнение вариантов

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

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

Управляемый режим

Стандарт для клиент-серверных баз с десятками и сотнями пользователей. Требует дисциплины разработки: все критичные изменения должны сопровождаться явными блокировками.

Смешанный режим

Используется как промежуточный этап перевода конфигурации. Ограничение: объекты в автоматическом режиме по-прежнему создают грубые блокировки.

Как работает механизм управляемых блокировок

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

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

Блокировки существуют в рамках транзакции: при её завершении (фиксации или откате) все установленные блокировки автоматически снимаются. Поэтому вызов Заблокировать() вне транзакции приведёт к ошибке. Это фундаментальное правило, которое часто нарушают начинающие разработчики.

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

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

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

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

Где и как разработчику ставить блокировки

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

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

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

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

Конфликты и взаимоблокировки: как диагностировать

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

Взаимоблокировка — более тяжёлый случай: сеанс А удерживает ресурс 1 и ждёт ресурс 2, а сеанс Б удерживает ресурс 2 и ждёт ресурс 1. СУБД автоматически обнаруживает тупик и аварийно завершает одну из транзакций. Типичная причина — разный порядок установки блокировок в разных процедурах: одна блокирует сначала товары, потом склады, другая — наоборот.

Диагностика ведётся через технологический журнал: события TLOCK, TDEADLOCK и TTIMEOUT показывают, какие сеансы, на каких таблицах и в каком порядке конфликтовали. Дополнительно в консоли кластера серверов 1С можно увидеть текущие блокировки и сеансы-владельцы. Для MS SQL Server полезны системные представления, показывающие цепочки ожиданий.

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

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

Поведение при параллельном проведении
Норма

Два документа по разным товарам проводятся одновременно без ошибок

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

Конфликт блокировки даже при непересекающихся данных — блокировка слишком широкая

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

События TDEADLOCK отсутствуют или единичны

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

Регулярные взаимоблокировки на одних и тех же таблицах

Длительность транзакций
Норма

Транзакции с блокировками короткие, без обращений к внешним ресурсам внутри

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

Внутри транзакции выполняются запросы к веб-сервисам или длительные расчёты

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

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

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

Типичные ошибки
01
Чтение остатков до установки блокировки — контроль остатков даёт ложные результаты при конкурентной записи
02
Блокировка без отбора по измерениям — весь регистр блокируется целиком, пользователи мешают друг другу
03
Разный порядок блокировки ресурсов в разных процедурах — возникают взаимоблокировки
04
Длинные транзакции с блокировками и обращениями к внешним сервисам — массовые таймауты у пользователей
05
Отсутствие обработки исключения конфликта в фоновых заданиях — регламентные операции падают без повторных попыток

Как перевести конфигурацию на управляемый режим

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

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

Маршрут решения

Как выбрать действие

Пользователи жалуются на ошибки «Конфликт блокировки» при одновременной работеПроанализируйте технологический журнал на события TLOCK и TTIMEOUT, найдите таблицу-источник и сузьте диапазон блокировки
В журнале регулярные взаимоблокировки (TDEADLOCK)Приведите порядок установки блокировок к единому во всех процедурах, работающих с этими таблицами
Конфигурация на автоматическом режиме и растёт число пользователейПланируйте поэтапный перевод через смешанный режим с тестированием на копии
Фоновое задание периодически падает с конфликтом блокировокДобавьте перехват исключения и повторные попытки с паузой между ними

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

Итог

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

Управляемые блокировки — это явная установка блокировок в коде через «БлокировкаДанных» внутри транзакции. Правильный шаблон: блокировка с отбором по измерениям → чтение → запись → фиксация. Главные риски — широкие блокировки, разный порядок блокирования ресурсов и длинные транзакции; диагностируются они через технологический журнал.

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

Можно ли использовать управляемые блокировки в файловой базе?

Да, режим поддерживается и в файловом варианте. Однако выигрыш в параллелизме будет ограничен собственными механизмами файловой СУБД. Полный эффект управляемый режим даёт в клиент-серверном варианте на MS SQL Server, PostgreSQL или Oracle.

Что произойдёт, если вызвать Заблокировать() вне транзакции?

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

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

Объектная блокировка при открытии формы — это пессимистическая блокировка конкретной ссылки, которую платформа накладывает автоматически, чтобы два пользователя не редактировали один объект. Управляемая блокировка через БлокировкаДанных работает на уровне диапазонов записей в транзакции и предназначена для защиты согласованности данных при расчётах и проведении, а не для разграничения интерактивного редактирования.

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

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

Нужно ли ставить блокировки при простом чтении данных для отчёта?

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

Как уменьшить количество взаимоблокировок в конфигурации?

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