Почему метод ПолучитьСоединенияИнформационнойБазы возвращает «Пользователь не идентифицирован» и как это исправить

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

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

Выясняем причину: изменение архитектуры и ошибка платформы

Для начала разберем, почему старый подход перестал работать. В современных версиях платформы 1С произошло разделение понятий «Сеанс» и «Соединение», которое стало более выраженным из-за оптимизации работы с серверными ресурсами. Рассмотрим два основных фактора:

  1. Внедрение пула соединений. Начиная с версии 8.3.19, система стала агрессивнее использовать механизм пула соединений. Теперь физическое соединение с базой данных (объект СоединениеИнформационнойБазы) может существовать отдельно от логического сеанса пользователя. Одно соединение может поочередно обслуживать разные сеансы. Если в конкретный момент времени через соединение не передаются данные от конкретного пользователя, оно считается «спящим» в пуле и не имеет привязки к конкретному объекту ПользовательИнформационнойБазы.
  2. Официальная ошибка 70123056. Фирма 1С признала наличие технической проблемы в релизах ветки 8.3.20. Суть ошибки заключалась в том, что при использовании тонкого клиента или запуске фоновых заданий данные о пользователе просто не пробрасывались в структуру соединения, даже если сеанс был активен.

Интересно заметить, что Толстый клиент и Конфигуратор обычно продолжают отображаться корректно. Это связано с тем, что они используют классический тип соединения, который жестко связывает процесс на компьютере пользователя с физическим соединением на сервере на все время работы приложения.

Различие между сеансами и соединениями

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

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

Метод ПолучитьСеансыИнформационнойБазы() — это именно то, что нам нужно для бизнес-логики. Он возвращает массив объектов типа СеансИнформационнойБазы. Сеанс — это логическое понятие «залогинившегося пользователя». Именно в сеансе всегда (за исключением критических ошибок платформы) корректно заполнены свойства Пользователь, ВремяНачала и ИмяКомпьютера.

Переходим на использование метода ПолучитьСеансыИнформационнойБазы

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


// Получаем массив всех активных сеансов
СписокСеансов = ПолучитьСеансыИнформационнойБазы();

Для Каждого ТекущийСеанс Из СписокСеансов Цикл
    // Игнорируем служебные сеансы, если это необходимо
    Если ТекущийСеанс.Пользователь <> Неопределено Тогда
        ИмяПользователя = ТекущийСеанс.Пользователь.Имя;
        ВремяВхода = ТекущийСеанс.НачалоСеанса;
        Компьютер = ТекущийСеанс.ИмяКомпьютера;
        
        // Выводим информацию или записываем в лог
        Сообщить("Пользователь: " + ИмяПользователя + " зашел в " + ВремяВхода);
    КонецЕсли;
КонецЦикла;

Обратите внимание, что объект СеансИнформационнойБазы содержит гораздо больше полезной информации для прикладного разработчика, чем старый объект соединения. Мы можем получить номер сеанса, используемое приложение (Тонкий клиент, Веб-клиент и т.д.) и даже связь с конкретным соединением через свойство НомерСоединения, если нам все же нужно сопоставить эти сущности.

Особенности работы с фоновыми заданиями

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

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


// В контексте выполняемого фонового задания
ТекущийСеанс = ПолучитьСеансыИнформационнойБазы()[0]; // Утрированный пример получения своего сеанса
// Лучше использовать:
ИмяТекущегоПользователя = ПользователиИнформационнойБазы.ТекущийПользователь().Имя;

Как окончательно решить проблему

Если в вашей организации критически важно использовать именно метод ПолучитьСоединенияИнформационнойБазы() (например, в старых типовых обработках или системах мониторинга), рассмотрите следующие шаги:

  1. Обновление платформы. Ошибка 70123056 была исправлена. Проанализируйте возможность перехода на релизы 8.3.20.1789 и выше или на ветки 8.3.21/8.3.22. В этих версиях стабильность заполнения поля пользователя была повышена.
  2. Рефакторинг кода. Это самый надежный путь. Замените все вызовы ПолучитьСоединения... на ПолучитьСеансы... там, где целью является получение списка работающих людей.
  3. Использование режима совместимости. Учтите, что изменение режима совместимости (например, установка «8.3.17») не всегда решает проблему, так как механизмы работы пула соединений на уровне ядра платформы все равно могут работать по новым правилам.

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

← На главную