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

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

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

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

  1. Режим управления блокировками – управляемый.
  2. Свойство регистра «Разделение итогов» – выключено.
  3. Свойство регистра «Использовать текущие итоги» – выключено.
  4. Дата актуальности итогов установлена раньше, чем период любой записываемой записи наборов записей.

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

Понимание условий, влияющих на блокировки

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

Управляемые блокировки

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

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

Отключенное «Разделение итогов»

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

Неиспользование «Текущих итогов»

Свойство регистра накопления «Использовать текущие итоги» определяет, будет ли система автоматически рассчитывать и поддерживать оперативные (актуальные на текущий момент) итоги по регистру. Если это свойство включено, то при каждом движении система должна либо пересчитывать итоги, либо обеспечивать их актуальность иным способом (например, отложенным обновлением). Это часто приводит к необходимости наложения блокировок на данные, участвующие в расчете итогов, чтобы избежать коллизий и обеспечить консистентность.

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

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

Еще одно важное условие, тесно связанное с предыдущим, – дата актуальности итогов установлена раньше, чем период любой записи наборов записей. Это означает, что все записываемые движения относятся к периоду, по которому система уже «закрыла» или «заморозила» расчет итогов. Для этих движений система точно не будет пытаться пересчитывать какие-либо итоговые значения, поскольку они находятся за пределами «актуального» периода итогов. Таким образом, это условие еще больше усиливает эффект от неиспользования текущих итогов, полностью исключая необходимость блокировок, связанных с их пересчетом.

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

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

Теперь, когда мы понимаем контекст, давайте рассмотрим, как именно управляемые блокировки будут себя вести при параллельной записи наборов записей регистра накопления при указанных условиях.

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

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

Блокировка по регистратору

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


Regions=AccRg1013.RECORDER,Locks='AccRg1013.RECORDER Exclusive Fld1000=0 Recorder=395:bb94d45d64bbe7e411ec3f05f1b55c06'

Эта запись говорит нам о следующем:

  1. AccRg1013 – это внутреннее имя регистра накопления.
  2. RECORDER – указывает, что блокировка наложена на поле, содержащее ссылку на документ-регистратор.
  3. Exclusive – тип блокировки, означающий, что только одна транзакция может изменять данные, находящиеся под этой блокировкой.
  4. Recorder=395:bb94d45d64bbe7e411ec3f05f1b55c06 – это конкретный идентификатор регистратора, на который наложена блокировка.

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

Влияние измерений

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

Тем не менее, важно понимать, что платформа 1С всегда стремится к обеспечению целостности данных. Даже если блокировка в первую очередь по регистратору, попытка записать движения, которые каким-либо образом нарушают внутреннюю логику регистра или уникальность (например, если регистр настроен на уникальность по измерениям + периоду для каждого регистратора), может привести к блокировке.

Сценарии параллельной записи

Давайте рассмотрим конкретные сценарии параллельной записи, основываясь на нашем анализе и эмпирических данных:

Сценарий 1: Параллельная запись движения разными регистраторами

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

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

  1. Транзакция 1 записывает движения Документа1. Система накладывает эксклюзивную блокировку на AccRg1013.RECORDER со значением Документ1.
  2. Транзакция 2 записывает движения Документа2. Система накладывает эксклюзивную блокировку на AccRg1013.RECORDER со значением Документ2.

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

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

Сценарий 2: Попытка изменения одного и того же регистратора двумя транзакциями

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

Причина: Обе транзакции будут претендовать на эксклюзивную блокировку для одного и того же значения поля RECORDER. Первая транзакция, которая успеет установить блокировку, заблокирует доступ для второй, пока не завершится.

Сценарий 3: Нюансы при совпадении измерений и периода

Необходимо обратить внимание на важный аспект, упомянутый в дополнительных материалах: "Если же две разные транзакции пытаются записать движения по *одинаковой комбинации значений измерений* в *один и тот же период*, произойдет конфликт блокировки, даже если эти движения создаются разными документами-регистраторами."

Это утверждение может показаться противоречащим нашим выводам о блокировке по регистратору. Однако, это скорее описывает более общий сценарий или ситуацию, когда платформа все же вынуждена обеспечивать какую-либо форму уникальности или консистентности на уровне измерений. В условиях, когда "Текущие итоги не используются" и "Дата актуальности итогов установлена раньше", платформа максимально снижает эту потребность. Эмпирический тест и запись из ТЖ (где блокировка явно на RECORDER) показывают, что в данном конкретном случае приоритет отдается блокировке по регистратору.

Мы полагаем, что упомянутый конфликт по измерениям и периоду (независимо от регистратора) может возникнуть в случае, если:

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

Верификация блокировок с помощью Технологического журнала (ТЖ)

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

Настройка Технологического журнала для событий блокировок

Для анализа блокировок нам необходимо настроить сбор событий TLOCK. Выполним следующие шаги:

  1. Откроем файл настроек ТЖ (обычно logcfg.xml), расположенный в каталоге установки сервера 1С:Предприятия или в каталоге рабочего процесса (rphost).
  2. Добавим или модифицируем секцию <log>, включив в нее фильтр для события TLOCK.

Пример настройки logcfg.xml:


<log>
    <event>
        <eq property="Name" value="TLOCK"/>
    </event>
    <property name="all"/>
</log>

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

Анализ записей TLOCK

Когда мы запустим наш эксперимент (например, две параллельные записи с разными регистраторами) и затем проанализируем файлы ТЖ, мы сможем увидеть записи типа:


Regions=AccRg1013.RECORDER,Locks='AccRg1013.RECORDER Exclusive Fld1000=0 Recorder=395:bb94d45d64bbe7e411ec3f05f1b55c06'

Давайте разберем эту запись подробнее:

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

Свойство «БлокироватьДляИзменения»

В контексте обсуждения блокировок регистров накопления часто упоминается свойство набора записей БлокироватьДляИзменения. Давайте выясним его назначение и актуальность в нашей ситуации.

Назначение свойства «БлокироватьДляИзменения»

Свойство БлокироватьДляИзменения набора записей регистра накопления само по себе не устанавливает блокировку. Его основное назначение — указать платформе, что при автоматической установке управляемой блокировки (которая происходит в момент записи набора записей) следует игнорировать разделитель итогов.

Это свойство актуально только тогда, когда:

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

Актуальность в нашем сценарии

В рассматриваемой нами ситуации свойство регистра «Разделение итогов» выключено. Следовательно, механизм разделителей итогов просто не используется. Из этого следует, что свойство БлокироватьДляИзменения, отвечающее за управление поведением блокировок относительно разделителей итогов, не будет иметь никакого смысла или влияния на поведение блокировок. Оно просто не будет задействовано платформой.

Практические рекомендации

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

  1. Используйте преимущества отключенных итогов: Если в вашей бизнес-логике нет необходимости в оперативном получении актуальных итогов, и их расчет может быть отложен (например, до конца дня, недели, или осуществляться регламентными заданиями), максимально используйте условия «Текущие итоги не используются» и раннюю «Дата актуальности итогов». Это существенно увеличит возможности параллельной записи.
  2. Обеспечьте уникальность регистраторов: При массовой загрузке данных или параллельном создании движений всегда стремитесь к тому, чтобы каждая логическая операция выполнялась своим уникальным регистратором (документом). Это позволит системе эффективно распределять блокировки по разным экземплярам регистраторов.
  3. Моделируйте и тестируйте: Самый надежный способ проверки поведения блокировок в вашей конкретной конфигурации — это моделирование сценариев параллельной работы и анализ Технологического журнала. Только так вы сможете быть полностью уверены в поведении вашей системы.
  4. Не злоупотребляйте ручными блокировками: В управляемом режиме 1С платформа достаточно интеллектуальна в управлении блокировками. Излишнее ручное наложение блокировок может, наоборот, снизить параллелизм и привести к дедлокам. Программно устанавливайте блокировки только в тех случаях, когда требуется защитить специфические участки данных, которые не покрываются автоматическими блокировками платформы.

Заключение

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

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

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

← На главную