При разработке и сопровождении систем на платформе 1С:Предприятие часто возникает ситуация, когда регламентное задание или длительная операция «зависает» или выполняется недопустимо долго. Стандартная отладка не всегда дает быстрый ответ, особенно если проблема проявляется эпизодически. В этой статье мы проанализируем ситуацию и рассмотрим комплекс методов, которые позволяют точно локализовать проблемный участок кода, даже если он выполняется часами.
Этот метод является наиболее наглядным и простым для реализации непосредственно из Конфигуратора. Если выполнение кода застряло на какой-то строке, мы можем включить замер и через некоторое время его остановить.
Разберем по шагам, как это сделать для регламентного задания:
-debug).После остановки замера 1С откроет таблицу с результатами. Проанализируем полученные данные: строка, которая выполняется в данный момент (или на которой система провела 99% времени), будет иметь максимальное значение в колонке «Время». Как показывает практика, чаще всего такой строкой оказывается Запрос.Выполнить().
Если проблема плавающая и проявляется раз в месяц, держать включенным замер производительности невозможно. В таком случае рассмотрим вариант внедрения диагностического кода. Этот метод надежен, так как данные сохраняются в текстовый файл или журнал регистрации независимо от сеанса отладки.
Пример реализации отладочного сообщения:
// Вставляем контрольные точки в подозрительных местах
ЗаписьЖурналаРегистрации("ОтладкаЗадания", УровеньЖурналаРегистрации.Информационный, , , "Начало этапа 1: " + ТекущаяДата());
// Ваш код...
ЗаписьЖурналаРегистрации("ОтладкаЗадания", УровеньЖурналаРегистрации.Информационный, , , "Завершение этапа 1, начало формирования запроса: " + ТекущаяДата());
Результат = Запрос.Выполнить();
ЗаписьЖурналаРегистрации("ОтладкаЗадания", УровеньЖурналаРегистрации.Информационный, , , "Запрос выполнен успешно: " + ТекущаяДата());
Проанализировав журнал регистрации после «зависания», мы легко увидим, между какими двумя метками возникла пауза в несколько часов. Помните: после завершения отладки обязательно удалите лишние вызовы ЗаписьЖурналаРегистрации или Сообщить, чтобы не замусоривать систему.
Для системных администраторов и опытных разработчиков выясним причину через Технологический журнал. Это мощный инструмент, который фиксирует события на уровне платформы. Чтобы поймать «зависшую» строку, нам нужно настроить сбор событий CALL (вызовы методов встроенного языка) и DBMSSQL (запросы к базе данных).
Пример настройки файла logcfg.xml для отслеживания длительных операций:
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="C:\LOGS\LongQueries" history="24">
<event query="DBMSSQL">
<property name="all"/>
</event>
<event query="CALL">
<property name="all"/>
</event>
<property name="Duration">
<condition property="Duration" value="1000000" courage="greater"/>
</property>
</log>
</config>
В данном примере в лог попадут только те события, длительность которых превышает 1000 секунд. Если регламентное задание стоит на месте, ТЖ зафиксирует начало события, но не запишет его окончание до тех пор, пока оно не завершится или процесс не будет убит.
Иногда нет времени настраивать логи, и нужно понять ситуацию «здесь и сейчас». Посмотрим на возможности консоли администрирования серверов 1С:
Если мы выяснили, что код стоит на Запрос.Выполнить(), проанализируем ситуацию на стороне SQL Server. С помощью SQL Server Profiler или системного представления sys.dm_exec_requests можно увидеть текст SQL-запроса, который выполняется в данный момент.
Запустите следующий скрипт в SQL Management Studio:
SELECT r.session_id, r.start_time, r.total_elapsed_time, st.text
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) st
WHERE r.session_id > 50 -- фильтр пользовательских процессов
ORDER BY r.total_elapsed_time DESC;
Это позволит увидеть «сырой» SQL-текст. Сопоставив его с метаданными 1С (именами таблиц типа _InfoReg123), вы поймете, какой именно запрос из модуля 1С вызывает задержку.
Существует еще один способ, упомянутый в обсуждении: использование команды «Отладка» — «Остановить». Однако у него есть важный нюанс. Разберем подробнее: эта команда сработает только в момент перехода интерпретатора от одной строки к другой. Если выполнение «намертво» зависло внутри метода Запрос.Выполнить() или внутри внешней компоненты, остановка не произойдет, пока управление не вернется в контекст встроенного языка 1С. Тем не менее, это первое, что стоит попробовать при живой отладке.
Подводя итог, можно сказать, что универсальной «кнопки», показывающей текущую строку без предварительной подготовки, не существует, но комбинация инструментов дает стопроцентный результат. Для оперативного поиска используйте замер производительности. Для долгосрочного мониторинга — технологический журнал и логирование. Если вы видите, что дело в запросе, переходите к анализу индексов и планов запроса на уровне СУБД, так как проблема чаще всего кроется не в самой «строке», а в объеме обрабатываемых данных или блокировках.