Как применять методы работы с высоконагруженными системами (HighLoad) в 1С?

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

Работа с высоконагруженными системами на платформе 1С:Предприятие 8 — это не просто умение писать код, а комплексный подход к архитектуре, который позволяет системе стабильно работать при одновременной работе сотен и тысяч пользователей. Когда перед разработчиком стоит задача реализовать складской учет в условиях HighLoad, стандартных подходов становится недостаточно. Разберем подробно, какие методы необходимо применять и почему они критически важны для производительности.

Использование управляемых блокировок данных

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

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


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

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

Новая методика контроля остатков: «Сначала пишем, потом проверяем»

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

Разберем этот алгоритм по шагам:

  1. Устанавливаем режим записи движений: Движения.ОстаткиНоменклатуры.Записывать = Истина;.
  2. Записываем пустые или предварительные наборы записей, чтобы «застолбить» место в транзакции.
  3. Выполняем запрос к виртуальной таблице Остатки, соединяя её с данными текущего документа.
  4. Если после записи обнаруживается отрицательный остаток, устанавливаем Отказ = Истина, что приведет к автоматическому откату транзакции.

Посмотрим на практическую реализацию такой проверки в процедуре ОбработкаПроведения:


// 1. Устанавливаем флаг записи, чтобы движения зафиксировались в базе перед проверкой
Движения.ОстаткиНоменклатуры.Записывать = Истина;
Движения.Записать(); 

// 2. Устанавливаем управляемую блокировку (как в примере выше)
// ... код блокировки ...

// 3. Проверяем остатки после записи
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Остатки.Номенклатура КАК Номенклатура,
    |   Остатки.КоличествоОстаток КАК Остаток
    |ИЗ
    |   РегистрНакопления.ОстаткиНоменклатуры.Остатки(&МоментВремени, Номенклатура В (&СписокНоменклатуры) И Склад = &Склад) КАК Остатки
    |ГДЕ
    |   Остатки.КоличествоОстаток < 0";

Запрос.УстановитьПараметр("МоментВремени", МоментВремени);
Запрос.УстановитьПараметр("СписокНоменклатуры", СписокНоменклатуры);
Запрос.УстановитьПараметр("Склад", Склад);

РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
    Отказ = Истина;
    // Сообщить пользователю о нехватке товара
КонецЕсли;

Механизм разделения итогов (Split Totals)

В складском учете часто возникает ситуация, когда сотни пользователей одновременно меняют остатки одной и той же популярной позиции. На уровне СУБД это вызывает борьбу за одну и ту же строку в таблице итогов. Чтобы решить эту проблему, в 1С существует свойство регистра «Разделение итогов».

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

Оптимизация транзакций и запросов

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

Рассмотрим пример индексации временной таблицы в Запросе:


Запрос.Текст = 
    "ВЫБРАТЬ Номенклатура, Количество ПОМЕСТИТЬ ВТ_Данные ИЗ &ТЧ ГДЕ ... ;
    |ИНДЕКСИРОВАТЬ ПО Номенклатура;
    |//////////////////////////
    |ВЫБРАТЬ ... ИЗ ВТ_Данные ЛЕВОЕ СОЕДИНЕНИЕ Регистр ...";

Асинхронная обработка и очереди

Если система не справляется с потоком документов в реальном времени, мы можем применить паттерн «Очередь». Вместо того чтобы проводить тяжелый документ сразу, мы можем просто записывать его, а само проведение выполнять в фоновом задании. Это позволяет пользователю мгновенно получить контроль над интерфейсом, пока сервер в фоновом режиме обсчитывает остатки и движения.

Многопоточность в 1С реализуется через ФоновыеЗадания. Однако, как верно подмечено в обсуждении, не стоит пытаться распараллеливать запись одной строки — накладные расходы на запуск потока превысят выигрыш. Многопоточность эффективна при пакетной обработке больших массивов данных или выполнении тяжелых регламентных операций.

Мониторинг и инструменты анализа

Невозможно оптимизировать систему, не зная, где именно она тормозит. Для работы с высоконагруженными системами программист 1С должен владеть следующими инструментами:

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

← На главную