В высоконагруженных системах на базе 1С:ERP, Комплексной автоматизации 2 или Управления торговлей 11 одной из самых частых и болезненных проблем являются блокировки в регистре ТоварыОрганизаций. Пользователи начинают массово получать сообщения о конфликтах при проведении обычных документов: «Приобретение товаров», «Перемещение», «Реализация». Проблема часто возникает внезапно и парализует работу склада и отдела продаж.
В этой статье мы подробно разберем, почему возникают эти блокировки, как проанализировать ситуацию и какие конкретные шаги нужно предпринять для стабилизации системы. Мы пройдем путь от проверки целостности данных до настройки серверной части.
Прежде всего, проанализируем, почему блокировки происходят именно в момент записи документа. В современных конфигурациях 1С расчет Видов запасов (определение того, чей товар списывается — собственный или комиссионный, по какому соглашению он пришел) происходит в процедуре ПередЗаписью модуля объекта. Система обращается к общему модулю ЗапасыСервер, где вызывается метод УстановитьБлокировкуРегистров(ДокументОбъект, МенеджерВременныхТаблиц).
Рассмотрим, что происходит внутри этого механизма. 1С пытается наложить управляемую блокировку на остатки по конкретной номенклатуре в разрезе организации и склада. Если в документе много строк или если в системе одновременно проводится несколько перемещений между одними и теми же складами, транзакции начинают выстраиваться в очередь. Если время ожидания превышает 20–40 секунд, пользователь получает ошибку конфликт блокировок.
Одной из самых неочевидных, но критических причин является наличие в базе документов с некорректными датами (так называемые «космические даты» или даты из далекого прошлого/будущего). Выясним, почему это важно. Если в регистре ТоварыОрганизаций появляется запись, например, от 2099 года, система при каждом проведении текущего документа пытается пересчитывать итоги, захватывая огромный временной диапазон. Это резко увеличивает время удержания транзакции.
Рекомендуем выполнить следующий запрос в консоли отчетов, чтобы выявить виновника:
ВЫБРАТЬ
ТоварыОрганизаций.Период КАК Период,
ТоварыОрганизаций.Регистратор КАК Регистратор
ИЗ
РегистрНакопления.ТоварыОрганизаций КАК ТоварыОрганизаций
ГДЕ
ТоварыОрганизаций.Период > &ТекущаяДата
ИЛИ ТоварыОрганизаций.Период < ДАТАВРЕМЯ(2010, 1, 1)
Если такие документы найдены, их необходимо исправить, перепровести или удалить лишние движения. Также крайне важно зайти в «Обслуживание» — «Регламентные операции» — «Управление итогами» и убедиться, что Период рассчитанных итогов установлен корректно (обычно это конец предыдущего месяца).
Если блокировки вызваны интенсивной работой пользователей, а не ошибками данных, рассмотрим архитектурное решение задачи. В 1С предусмотрен механизм разнесения во времени проведения документа и тяжелых расчетов по видам запасов.
Выполним следующие настройки в интерфейсе программы:
После включения этой опции документ будет проводиться быстро, записывая только основные данные, а распределение видов запасов и формирование движений по регистру ТоварыОрганизаций будет выполнять фоновое задание. Это позволит разгрузить пользователей и устранить большинство конфликтов в реальном времени.
Часто программисты пытаются «оптимизировать» проведение, отключая заполнение видов запасов для определенных типов документов (как упоминалось в обсуждении для «Передачи продукции из кладовой»). Однако, если при этом в общем модуле ЗапасыСервер продолжает вызываться стандартная блокировка, она может блокировать «пустое пространство».
Важный момент: Если в наборе записей для блокировки передана пустая ссылка на склад или номенклатуру, система может заблокировать вообще все записи по организации. Проанализируем код в ПередЗаписью:
Если Не ПроизводитсяОбновлениеИБ Тогда
ЗапасыСервер.УстановитьБлокировкуРегистров(ДокументОбъект, МенеджерВременныхТаблиц);
КонецЕсли;
Если вы делаете доработки, убедитесь, что в менеджер временных таблиц не попадают пустые значения ключевых измерений. Также стоит проверить, не включен ли в системе RLS (ограничение доступа на уровне записей). Если RLS активен, 1С добавляет дополнительные условия к каждому SQL-запросу, что может привести к эскалации блокировок с уровня строк до уровня всей таблицы.
Посмотрим на проблему со стороны инфраструктуры. Регистр ТоварыОрганизаций является одним из самых «пухлых». При интенсивной вставке и удалении записей индексы таблиц итогов фрагментируются. Разберем шаги по обслуживанию базы:
_AccumReg... выше 30%, время поиска записей для блокировки увеличивается в разы.Разделение итогов для данного регистра. Это позволяет разным транзакциям обновлять итоги одновременно, используя разные «слои» данных.Если вышеописанные меры не помогают, перейдем к глубокой диагностике. Нам нужно настроить сбор событий TLOCK и TTIMEOUT в Технологическом журнале (ТЖ). Это позволит увидеть, какая именно транзакция держит блокировку и какой процесс её ждет.
Пример настройки logcfg.xml для поиска виновника:
<event query="true">
<eq property="Name" value="TLOCK"/>
<property name="all"/>
</event>
<event query="true">
<eq property="Name" value="TTIMEOUT"/>
<property name="all"/>
</event>
Проанализировав логи, мы сможем увидеть конкретную строку кода и значения измерений, на которых произошел конфликт. Часто оказывается, что виноват не основной процесс проведения, а, например, фоновое задание обмена с сайтом или неоптимальный отчет, который кто-то запустил в разгар рабочего дня с использованием ДЛЯ ИЗМЕНЕНИЯ в запросе.
Подводя итог, можно сказать, что решение проблемы блокировок по ТоварыОрганизаций всегда комплексно. Сначала мы исключаем «мусор» в данных (даты и итоги), затем проверяем корректность типовых настроек (отложенное проведение) и в последнюю очередь переходим к анализу кода и SQL-оптимизации. Помните, что стабильность работы склада напрямую зависит от скорости транзакций в этом регистре, поэтому любые доработки в этой области должны проходить тщательное нагрузочное тестирование.