Как спроектировать высоконагруженный регистр в 1С для работы с задачами без блокировок?

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

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

Выбор типа регистра и его структуры

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

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

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

Отказ от записи при открытии формы

Одной из самых критичных ошибок, упомянутых в обсуждении, является фиксация прочтения задачи (запись в регистр) непосредственно в момент открытия формы. Выясним причину, почему это плохо: любая запись (INSERT или UPDATE) накладывает эксклюзивную блокировку (X-lock) на уровне СУБД. Если в этот же момент другой процесс (например, фоновое задание по распределению задач) пытается обновить этот же набор данных, возникает ожидание или Deadlock.

Посмотрим, как можно решить эту задачу иначе:

Использование механизма Read Committed Snapshot (RCSI)

Для платформы 1С:Предприятие 8.3 крайне важно использование режима READ_COMMITTED_SNAPSHOT на стороне MS SQL Server. Это механизм версионности строк, который позволяет читающим транзакциям не блокироваться пишущими. Рассмотрим, как это работает: когда один процесс пишет данные в регистр, 1С (при включенном RCSI) позволяет остальным пользователям читать "последнюю зафиксированную" версию данных из tempdb, не выстраивая очередь ожиданий.

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


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

Оптимизация частого опроса (Polling)

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

1. Система взаимодействия (Collaboration System). Это наиболее современный и правильный подход. Вместо того чтобы клиент "спрашивал" сервер, сервер сам "толкает" уведомление клиенту через WebSocket-соединение. Это полностью исключает нагрузку на SQL-сервер, связанную с постоянными холостыми запросами.

2. Использование буферных таблиц (Buffer Tables). Если запись в основной регистр происходит очень часто, можно применить стратегию "очереди". Данные сначала пишутся в максимально легкую таблицу (минимум индексов, никакой логики), а раз в минуту регламентное задание переносит накопленные данные в основной высоконагруженный регистр. Это позволяет распределить нагрузку на дисковую подсистему.

3. Секционирование данных на уровне логики. Если количество записей в регистре исчисляется миллионами, а сотрудников тысячи, можно добавить измерение-разделитель (например, НомерГруппы). Это позволит СУБД более эффективно распределять данные по страницам памяти и уменьшит вероятность Page Locks (блокировок страниц данных).

Тонкие настройки СУБД для регистра

Посмотрим на ситуацию со стороны системного администратора. Для регистра, в который пишут каждые несколько секунд, полезно настроить Fill Factor (коэффициент заполнения индексов). По умолчанию он равен 0 (или 100%), что означает максимально плотную упаковку данных. При частых вставках это вызывает "расщепление страниц" (Page Splits). Установив Fill Factor на уровне 80%, мы оставим свободное место в страницах данных для новых записей, что значительно ускорит операции INSERT.

Также рекомендуется включить параметр Optimize for Ad Hoc Workloads на уровне SQL Server. Поскольку запросы к регистру могут приходить с разными параметрами от сотен пользователей, это поможет не засорять кэш планов неэффективными одноразовыми планами выполнения.

Резюме по проектированию

Подводя итог, для создания стабильного высоконагруженного регистра задач мы должны:

  1. Использовать независимый регистр сведений с правильным порядком измерений в индексе.
  2. Минимизировать транзакции на чтение, заменив частые опросы Системой взаимодействия.
  3. Удалить все механизмы записи при чтении или открытии форм.
  4. Убедиться, что база работает в режиме RCSI и используются управляемые блокировки.
  5. Рассмотреть внедрение буферных таблиц для снижения мгновенной нагрузки при записи.
← На главную