Как устранить конфликт блокировок и проводить документы во время расчета себестоимости в 1С:УПП

Программист 1С v8.3 (Обычные формы) Управленческий учет Промышленность, строительство и АПК
← На главную

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

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

Выясняем техническую причину блокировок

Для начала проанализируем архитектуру работы базы данных в момент расчета себестоимости. Конфигурация 1С:УПП 1.3 исторически разрабатывалась в режиме автоматических блокировок данных. В этом режиме управление блокировками таблиц полностью перекладывается на систему управления базами данных (СУБД), например, MS SQL Server или PostgreSQL.

Когда мы запускаем стандартное проведение документа «Расчет себестоимости выпуска», платформа открывает одну гигантскую транзакцию, внутри которой выполняются миллионы математических расчетов, корректировок регистров и запросов. СУБД, стремясь обеспечить максимальную согласованность данных (уровень изоляции транзакций Repeatable Read или Serializable), начинает накладывать блокировки на все считываемые и изменяемые таблицы.

В процессе работы возникают два ключевых фактора:

  1. Эскалация (укрупнение) блокировок. Если транзакция РСВ блокирует более 5000 строк в одной таблице (например, в регистре «Учет затрат»), СУБД автоматически заменяет тысячи мелких строчных блокировок на одну монопольную блокировку всей таблицы. С этого момента ни один другой пользователь не может записать данные в эту таблицу.
  2. Блокировка системных таблиц (констант и параметров сеанса). Любой документ в системе, даже полностью самописный, при проведении или записи обращается к системным механизмам конфигурации. Происходит обращение к функциональным опциям, чтение констант (например, валюты регламентированного учета, признаков ведения партионного учета) и инициализация параметров сеанса (проверка прав доступа, текущего пользователя). Поскольку РСВ в своей огромной транзакции также читал эти константы, СУБД накладывает разделяемую блокировку на всю таблицу констант _Consts. Другой пользователь, пытаясь провести свой документ, пытается обновить или прочитать ту же таблицу, натыкается на блокировку РСВ, ожидает 20 секунд и отваливается по таймауту.

Почему ситуация ухудшается после обновления релиза УПП?

Часто ИТ-службы замечают, что на старых релизах УПП (например, 1.3.113.4) расчет себестоимости позволял пользователям работать в фоне, а после обновления на более свежий релиз (например, 1.3.122.2) база начинает намертво зависать. Это связано с развитием конфигурации:

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

Решение 1: Использование механизма проведения вне транзакции

Самый быстрый и эффективный способ вернуть пользователям возможность работать во время расчета себестоимости — задействовать штатную настройку самого документа РСВ. Давайте разберем этот механизм.

В документе «Расчет себестоимости выпуска» предусмотрена специальная настройка — флаг (кнопка в меню «Действия») «Провести вне транзакции». По умолчанию, если эта настройка отключена, весь расчет выполняется в одной неделимой транзакции СУБД. Если включить этот режим, логика работы кардинально меняется:

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

Решение 2: Оптимизация обращения к константам и кэширование

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


// Неоптимальный код: прямое обращение к константе в транзакции проведения
Если Константы.ИспользоватьЛимитыОстатков.Получить() Тогда
    // Выполнение логики проверки лимитов
КонецЕсли;

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


// Оптимальный код: чтение значения из кэшированного общего модуля
ИспользоватьЛимиты = МойОбщийМодульПовторногоИспользования.ПолучитьИспользоватьЛимитыОстатков();
Если ИспользоватьЛимиты Тогда
    // Выполнение логики проверки лимитов
КонецЕсли;

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

Решение 3: Локализация блокировок с помощью управляемого режима

Если ваша база данных существенно доработана, хорошим решением будет точечный перевод самописных документов и критически важных регистров на управляемый режим блокировок. Это позволит вам вручную указывать платформе, какие именно данные нужно заблокировать, не полагаясь на избыточные автоматические блокировки СУБД.

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


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

// Блокируем данные только по конкретной организации и периоду
ЭлементБлокировки.УстановитьЗначение("Организация", СсылкаНаОбъект.Организация);
ЭлементБлокировки.УстановитьЗначение("Период", Новый Диапазон(НачалоМесяца(Дата), КонецМесяца(Дата)));

Блокировка.Заблокировать();

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

Решение 4: Мониторинг через Технологический журнал (ТЖ)

Чтобы со стопроцентной точностью определить, какая именно строка кода или таблица СУБД выступает инициатором блокировки, необходимо настроить сбор технологического журнала на сервере «1С:Предприятие». Создадим файл конфигурации logcfg.xml в каталоге установки платформы со следующим содержимым:


<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/tech-log">
  <log location="C:\v8\logs\locks" history="24">
    <event>
      <eq property="Name" value="TTIMEOUT"/>
    </event>
    <event>
      <eq property="Name" value="TLOCK"/>
    </event>
    <property name="all"/>
  </log>
</config>

Проанализировав файлы логов после возникновения ошибки «Конфликт блокировок транзакций», мы увидим точные имена таблиц базы данных (например, _InfoRegXXXX или _Consts) и контекст исполнения на встроенном языке 1С, который привел к ожиданию и сбою.

Решение 5: Включение разделения итогов для регистров

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

Убедимся, что на вкладке «Данные» у этих регистров установлен флаг «Разделение итогов». Данный механизм позволяет платформе записывать движения разных транзакций во временные независимые таблицы дельт, объединяя их позже в фоновом режиме. Это значительно снижает вероятность взаимных блокировок при одновременной работе пользователей и расчета себестоимости.

Дополнительные рекомендации для стабильной работы

Для минимизации конфликтов во время проведения РСВ рекомендуется придерживаться следующих правил:

← На главную