Как устранить конфликты блокировок и падение производительности в 1С:ЗУП 3.1 при некорректных датах в регистрах?

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом
← На главную

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

Симптомы проблемы: когда перезапуск служб дает лишь временный эффект

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

  1. Аномальное потребление ресурсов: Процессы sqlservr.exe и rphost.exe захватывают практически всю доступную оперативную память.
  2. Рост временных файлов: На диске сервера СУБД стремительно сокращается место из-за разрастания базы tempdb.
  3. Призрачные сеансы: В конфигураторе при попытке обновления или сохранения конфигурации система сообщает об активных пользователях, хотя в консоли «Администрирование серверов 1С» список сеансов пуст.
  4. Неэффективность перезапуска: Перезапуск служб 1С и SQL помогает лишь на короткое время (от нескольких минут до пары часов), после чего проблема возвращается в случайных документах.

Проанализируем ситуацию: если обычные методы оптимизации (обновление платформы, тестирование и исправление chdbfl.exe) не приносят результата, значит, корень проблемы кроется в самих данных, которые инициируют «тяжелые» транзакции.

Диагностика с помощью Технологического журнала 1С

Для того чтобы понять, какой именно запрос вызывает блокировку, нам необходимо настроить Технологический журнал (ТЖ). Это позволит увидеть полную картину событий в момент возникновения ошибки. Рассмотрим пример настройки файла log.cfg для отслеживания длительных запросов и блокировок:


<config xmlns="http://v8.1c.ru/v8/tech-log">
  <log location="C:\LOGS\LOCKS" history="24">
    <event>
      <eq property="Name" value="DBMSSQL"/>
      <gt property="Duration" value="100000"/>
    </event>
    <event>
      <eq property="Name" value="TLOCK"/>
    </event>
    <property name="all"/>
  </log>
</config>

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

Анализ на уровне СУБД: Флаги трассировки

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

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

Корень проблемы — некорректные даты (кейс с 2301 годом)

Выясним причину, почему обычные запросы в ЗУП начинают «съедать» память и диск. Часто это происходит из-за ошибочного ввода данных. Рассмотрим пример: через внешнюю обработку или из-за программной ошибки в регистры (например, РегистрРасчета.Начисления или РегистрНакопления.ДанныеОНачисленияхДляРасчетаСреднегоЗаработка) попадает запись с датой в далеком будущем (например, 01.01.2301).

Почему это убивает систему? В ЗУП реализованы сложные механизмы расчета периодов. При обращении к виртуальным таблицам за текущий период система пытается сопоставить данные, выстраивая временную шкалу от текущего момента до максимальной даты в регистре. Если эта дата — 2301 год, SQL Server пытается сформировать в памяти (и в tempdb) гигантские таблицы перерасчетов за 280 лет. Это вызывает лавинообразный рост нагрузки, блокировки и аварийное завершение рабочих процессов rphost (что объясняет «призрачные» сеансы в конфигураторе).

Как найти и устранить некорректные записи

Чтобы найти виновника, нам нужно просканировать основные регистры на предмет дат, выходящих за разумные пределы. Мы можем воспользоваться консолью запросов или выполнить прямой запрос к SQL-таблицам (для опытных администраторов). Разберем пример запроса для поиска записей в регистре расчета:


ВЫБРАТЬ
    Начисления.Регистратор,
    Начисления.ПериодРегистрации,
    Начисления.Сотрудник
ИЗ
    РегистрРасчета.Начисления КАК Начисления
ГДЕ
    Начисления.ПериодРегистрации > ДАТАВРЕМЯ(2030, 1, 1)
    ИЛИ Начисления.ПериодДействияНачало > ДАТАВРЕМЯ(2030, 1, 1)

Аналогичные проверки следует провести для регистров накопления, связанных с расчетом зарплаты. После обнаружения таких записей их необходимо удалить. Внимание: удаление через SQL напрямую крайне не рекомендуется, лучше использовать стандартные средства 1С (обработку «Выгрузка и загрузка данных XML» или написание простой процедуры удаления записей по набору).

Очистка очереди перерасчетов

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

  1. Перейдем в раздел Зарплата — Сервис — Перерасчеты.
  2. Проверим наличие записей с аномальными датами.
  3. Удалим все записи, которые относятся к некорректным периодам.

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

Профилактика: как не допустить повторения ситуации

Чтобы подобные инциденты не повторялись, проанализируем возможности защиты системы:


Если ПериодЗаписи > КонецГода(ТекущаяДата()) + 3600*24*365*2 Тогда // Ограничение +2 года
    Сообщить("Попытка записи данных с некорректной датой!");
    Отказ = Истина;
КонецЕсли;

Подводя итог, отметим: конфликты блокировок в ЗУП 3.1 далеко не всегда связаны с недостатком мощности сервера или ошибками в программном коде. Часто это результат «логической ошибки» в данных, которая заставляет механизмы расчета 1С работать в экстремальных режимах. Регулярный мониторинг дат в регистрах и настройка Технологического журнала — лучшие способы предотвратить подобные коллапсы.

← На главную