Вопрос корректной работы с блокировками в системе 1С:Предприятие 8.3 является критически важным при проектировании высоконагруженных систем, особенно когда речь идет о параллельной обработке данных в несколько потоков. Рассмотрим основные принципы взаимодействия платформы 1С с СУБД, разберем механизмы управляемых блокировок и выясним, как реализовать массовую загрузку данных без ошибок доступа.
Первое, что нам необходимо усвоить — это принципиальная разница в уровне гранулярности блокировок между режимами работы базы данных. Проанализируем их:
Таким образом, переход на клиент-серверный вариант работы — это первый и обязательный шаг для реализации параллельной обработки данных.
Разберем понятие управляемых блокировок. В современных конфигурациях 1С используется преимущественно управляемый режим блокировок. В этом режиме платформа берет на себя ответственность за логическую целостность данных, а СУБД (например, MS SQL Server) работает в режиме Read Committed Snapshot Isolation (RCSI).
Посмотрим, что это дает программисту: читающие транзакции больше не блокируются пишущими. Когда вы читаете данные запросом, вы получаете "снимок" данных, актуальный на момент начала транзакции. Однако, если вы планируете сначала прочитать данные, а затем на их основе выполнить расчет и запись, вам необходимо явно установить управляемую блокировку, чтобы "застолбить" этот диапазон данных и не дать другим процессам изменить его до завершения вашей транзакции.
Пример установки управляемой блокировки в коде:
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиТоваров");
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
ЭлементБлокировки.УстановитьЗначение("Склад", ВыбранныйСклад);
Блокировка.Заблокировать();
Важно понимать: управляемая блокировка существует только в памяти менеджера блокировок кластера 1С. СУБД о ней ничего не знает до момента реальной попытки записи в таблицу.
Проанализируем ситуацию, когда многопоточная загрузка внезапно начинает вызывать ошибки блокировок, хотя данные в потоках гарантированно уникальны. Причиной часто становится эскалация.
Эскалация — это процесс автоматического укрупнения блокировки. Она бывает двух видов:
Для предотвращения эскалации при массовой загрузке следует записывать данные порциями (пакетами). Рассмотрим пример оптимальной структуры цикла загрузки:
// Загрузка порциями по 1000 строк для предотвращения эскалации
Для Каждого ПорцияИзДанных Из ОбщийМассивДанных Цикл
НачатьТранзакцию();
Попытка
// Обработка и запись данных
ЗаписатьНаборДанных(ПорцияИзДанных);
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
// Логирование ошибки
КонецПопытки;
КонецЦикла;
Выясним, почему при записи в регистры накопления или бухгалтерии часто возникают конфликты, даже если регистраторы у документов разные. Проблема кроется в таблицах итогов. При записи движения платформа пытается обновить текущие итоги в одной строке по набору измерений. Если два потока пишут движения по одному и тому же складу и товару, они столкнутся на обновлении итогов.
Для решения этой проблемы в платформе предусмотрен механизм Разделения итогов. Рассмотрим, как он работает: платформа создает несколько физических записей для одного и того же набора измерений. Каждый поток обновляет свою "копию" строки, не мешая остальным. При чтении итогов система просто суммирует эти значения. Обязательно включите свойство "Разделение итогов" для регистров, в которые планируется интенсивная параллельная запись.
Рассмотрим рекомендации по реализации задачи автора (загрузка 10 млн строк через фоновые задания):
РегистрыНакопления.НужныйРегистр.УстановитьИспользованиеИтогов(Ложь). Это многократно ускорит запись, так как системе не придется тратить ресурсы на обновление агрегатов. После загрузки итоги нужно включить и пересчитать.Мы выяснили, что в клиент-серверном режиме 1С многопоточная запись вполне достижима. Главное — следить за границами транзакций, избегать порогов эскалации (100 000 объектов в 1С и 5 000 в SQL) и использовать встроенные механизмы платформы, такие как разделение итогов и управляемые блокировки данных. Соблюдение этих правил позволит сократить время обработки огромных массивов данных с нескольких дней до нескольких часов.