Что такое несовместимые блокировки в 1С и когда они возникают?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Суть понятия совместимости блокировок

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

Блокировки двух различных транзакций считаются несовместимыми только тогда, когда одновременно выполняются два условия:

  1. Несовместимы режимы блокировок — одна или обе транзакции претендуют на эксклюзивный доступ к ресурсу.
  2. Пересекаются пространства блокировок — обе транзакции пытаются заблокировать одну и ту же область данных (одну таблицу, одинаковый набор измерений, пересекающийся диапазон).

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

Режимы блокировок и таблица совместимости

В управляемом режиме 1С используются два основных режима установки транзакционных блокировок через свойство РежимБлокировкиДанных:

  1. Разделяемый (Shared, S) — РежимБлокировкиДанных.Разделяемый. Используется для чтения данных, которые не должны быть изменены другими транзакциями до завершения текущей. Несколько сеансов могут одновременно удерживать разделяемую блокировку на одну и ту же область.
  2. Исключительный (Exclusive, X) — РежимБлокировкиДанных.Исключительный. Используется для записи или подготовки к изменению данных. Только одна транзакция может удерживать исключительную блокировку на конкретный ресурс.

Проанализируем матрицу совместимости двух параллельных транзакций:

  1. Разделяемый + Разделяемый: Совместимы. Обе транзакции могут параллельно считывать заблокированную область данных.
  2. Разделяемый + Исключительный: Несовместимы. Если одна транзакция читает данные с разделяемой блокировкой, вторая не может получить исключительную блокировку на эту же область и будет ждать.
  3. Исключительный + Разделяемый: Несовместимы. Пока идет запись или подготовка с исключительной блокировкой, другие сеансы не могут читать данные с разделяемой блокировкой.
  4. Исключительный + Исключительный: Несовместимы. Две транзакции не могут одновременно изменять одну и ту же область данных.

Что такое пространство блокировки и как возникает пересечение

Рассмотрим подробнее понятие пространства блокировки. Пространство определяется именем таблицы метаданных (например, РегистрНакопления.ОстаткиНоменклатуры) и значениями полей или измерений этой таблицы.

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

  1. Точечная блокировка: если мы явно передаем склад и номенклатуру, блокируется только конкретная комбинация этих значений.
  2. Блокировка по умолчанию (пустое условие): если для какого-либо измерения не задано значение фильтра, менеджер считает, что заблокировано все пространство возможных значений по данному измерению.

Посмотрим на пример: первая транзакция блокирует остатки по всей номенклатуре для Склад = Склад1 (поле Номенклатура не указано). Вторая транзакция пытается установить блокировку на Склад = Склад1 и Номенклатура = Товар1. Поскольку первая транзакция захватила весь склад целиком, их пространства пересекаются, и вторая транзакция переходит в состояние ожидания.

Практический пример правильной установки управляемой блокировки

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


Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ТоварыНаСкладах");
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;

// Указываем источник данных, содержащий точечный список складов и номенклатуры
ЭлементБлокировки.ИсточникДанных = ТаблицаТоваров;
ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Склад", "Склад");
ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");

// Устанавливаем блокировку внутри транзакции
Блокировка.Заблокировать();

В этом примере блокируются строго те строки регистра, которые содержатся в ТаблицаТоваров, не затрагивая другие позиции номенклатуры и другие склады.

Причины конфликтов и способы их предотвращения

Проанализируем распространенные сценарии, приводящие к несовместимым блокировкам и взаимоблокировкам (Deadlock), а также методы их решения:

  1. Неполная гранулярность условий. Если не передавать в объект БлокировкаДанных все ключевые измерения, происходит захват избыточных данных. Всегда заполняйте все измерения регистра, по которым выполняется контроль.
  2. Разный порядок захвата ресурсов. Если транзакция А блокирует сначала Товар1, а затем Товар2, а параллельная транзакция Б — сначала Товар2, а затем Товар1, при исключительных блокировках возникнет взаимоблокировка (Deadlock). Решение: всегда упорядочивать коллекции строк в источниках блокировок по единому правилу (например, по возрастанию ссылки).
  3. Длительные транзакции. Любая управляемая блокировка удерживается до момента вызова ЗафиксироватьТранзакцию() или ОтменитьТранзакцию(). Снять ее раньше программно невозможно. Выносите тяжелые расчеты, заполнение интерфейсных структур и выборки данных, не требующие блокировки, за пределы явных транзакций.
  4. Конкуренция при обновлении итогов регистров. При массовой параллельной записи в одни и те же регистры накопления используйте свойство метаданных ИспользоватьРазделениеИтогов. Это позволяет транзакциям параллельно записывать движения, избегая очередей на агрегатные таблицы итогов.
  5. Автоматическое удаление движений. Если у документа включено свойство УдалятьДвиженияАвтоматически, платформа в самом начале транзакции проведения накладывает исключительные блокировки на таблицы регистров для очистки старых движений, что увеличивает время удержания несовместимых блокировок. Предпочтительнее использовать управляемое удаление движений.

Диагностика несовместимых блокировок

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

  1. TLOCK — фиксирует установку и снятие управляемых блокировок, отображая область (Regions) и режим (Locks).
  2. TTIMEOUT — регистрирует факт превышения времени ожидания на несовместимой блокировке с указанием виновного соединения (WaitConnections).
  3. TDEADLOCK — фиксирует обнаружение взаимной блокировки между процессами, которую платформа разрешает аварийным откатом одной из транзакций.
← На главную