При реализации обмена данными через веб-сервисы разработчики часто сталкиваются с ситуацией, когда код, успешно работающий в обычном или тонком клиенте, начинает вести себя непредсказуемо в серверном контексте веб-сервиса. Одной из наиболее труднодиагностируемых проблем является «вечный вис» при попытке программного создания объекта отчета с помощью менеджера: Отчеты[ИмяОтчета].Создать(). Особенно остро эта проблема проявляется при работе в распределенных системах, например, при использовании реплик базы данных SQL Server (AlwaysOn).
В этой статье мы подробно разберем, почему возникает подобное зависание, как его диагностировать и какие шаги необходимо предпринять для восстановления стабильной работы системы. Рассмотрим ситуацию по шагам, от анализа программного кода до глубокой проверки настроек сервера и базы данных.
Первым делом проанализируем, что происходит в момент вызова метода Создать(). Даже если модуль объекта отчета кажется вам практически пустым (содержит только обработчик ПриКомпоновкеРезультата), платформа 1С выполняет инициализацию объекта, которая включает в себя несколько скрытых этапов.
Важно понимать: сеанс веб-сервиса является неинтерактивным. Это означает, что любое обращение к методам или переменным, требующим взаимодействия с пользователем, приведет к блокировке потока. Платформа будет ожидать реакции пользователя, которого в данном контексте просто не существует.
Разберем основные причины зависания на этапе инициализации:
ПриНачалеРаботыСистемы или подписках на события) есть код, пытающийся открыть форму или вызвать модальное окно, веб-сервис «зависнет» навсегда.Для проверки этой гипотезы попробуем временно закомментировать весь код в модуле объекта и проверить, сохранится ли зависание при вызове:
// В модуле веб-сервиса
Попытка
ОбъектОтчет = Отчеты[ИмяОтчета].Создать();
Исключение
ЗаписьЖурналаРегистрации("Ошибка.СозданиеОтчета", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;
Одной из самых частых причин странного поведения новых объектов в 1С является некорректное обновление кэша. Если новый отчет был добавлен в конфигурацию недавно, а обновление базы выполнялось "динамически" (без остановки сервера), сервер приложений или веб-сервер (IIS/Apache) могли сохранить старую структуру метаданных.
Проанализируем шаги по очистке кэша:
iisreset. В случае Apache — перезапустите соответствующую службу.Если ваша база данных развернута в архитектуре AlwaysOn и веб-сервис обращается к Secondary Replica (доступной только для чтения), причина зависания может крыться на уровне SQL-сервера. Рассмотрим механизм блокировок.
Хотя метод Создать() кажется операцией чтения, платформа 1С при инициализации объекта может пытаться выполнить запись во временные таблицы (например, для кэширования схем компоновки или проверки прав). Если настройки подключения ApplicationIntent=ReadOnly настроены некорректно или права пользователя SQL ограничены, процесс может уйти в бесконечное ожидание блокировки типа LCK_M_....
Выясним причину с помощью SQL Profiler. Настроим отслеживание событий Errors and Warnings -> Blocked process report и Locks -> Lock:Acquisition. Если вы видите, что процесс 1С ожидает освобождения ресурса при обращении к системным таблицам метаданных, проблема кроется в режиме работы реплики.
Метод Создать() инициализирует компоновщик настроек на основании СхемыКомпоновкиДанных. Если СКД нового отчета содержит критические ошибки или избыточную сложность, платформа может «зациклиться» при попытке её валидации.
Проанализируем возможные проблемы в СКД:
Для диагностики попробуем следующий прием: временно заменим основную схему компоновки данных в "проблемном" отчете на самую простую (например, ВЫБРАТЬ 1 КАК Поле). Если после этого метод Создать() отработает мгновенно — проблему нужно искать внутри структуры исходной СКД.
Выясним, нет ли ограничений на уровне операционной системы. Веб-сервис исполняется от имени учетной записи, под которой запущен пул приложений веб-сервера (например, IUSR или NetworkService). Эта учетная запись может не иметь прав на временные папки (Temp), которые необходимы платформе 1С для компиляции объектов.
Также стоит проверить использование внешних компонент. Если ваш отчет при инициализации обращается к ПодключитьВнешнююКомпоненту(), убедитесь, что библиотека зарегистрирована на сервере и доступна для системного пользователя веб-сервера.
Если ни один из вышеперечисленных методов не помог, существует вероятность повреждения структуры метаданных самого объекта в базе данных. Выполним следующие действия:
.cf, создать новую пустую базу и загрузить конфигурацию туда. Если в новой базе отчет создается без проблем, значит, дело в конкретном экземпляре информационной базы.Подводя итог, можно сказать, что зависание Отчеты[...].Создать() в веб-сервисе — это комплексная проблема, которая чаще всего решается либо очисткой серверного кэша, либо устранением неинтерактивных вызовов в модулях объекта и глобальных модулях системы.