Сеанс.blockedByDBMS

Свойства · blockedByDBMS

Тип: Число. Содержит номер сеанса, который является причиной ожидания транзакционной блокировки, в том случае, если сеанс исполняет запрос к СУБД и ожидает транзакционную блокировку, установленную другим сеансом. Иначе - 0.

Полное описание, параметры и ограничения

Сеанс.blockedByDBMS (ISessionInfo.blockedByDBMS)

Сеанс (ISessionInfo)

blockedByDBMS (blockedByDBMS)

Доступен, начиная с версии 8.2.

Использование:
Только чтение.
Описание:
Тип: Число.
Содержит номер сеанса, который является причиной ожидания транзакционной блокировки, в том случае, если сеанс исполняет запрос к СУБД и ожидает транзакционную блокировку, установленную другим сеансом. Иначе - 0.
Доступность:

Интеграция.

Использование в версии:

Доступен, начиная с версии 8.2.

Методическая информация

Практические примеры

Увидеть блокировщика, не принимая его ID за секунды

Читаем два номера блокирующих сеансов, признак захваченного соединения СУБД и длительность захвата.

Где и как запускать

Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.

Подготовка

  1. Только собственный изолированный тестовый кластер на Windows. Зарегистрированная в нём база называется guide-owned-session-lab, имя конфигурации этой базы УчебнаяБазаСеансов. Запустите в ней отдельный учебный клиент.

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

  3. V85.COMConnector должен быть уже зарегистрирован администратором на Windows-сервере 1С с подходящей разрядностью. Пример ничего не устанавливает и не регистрирует. Если COM недоступен, остановитесь и обратитесь к администратору тестового стенда.

  4. В форме собственной обработки создайте строковые реквизиты КлючКластера, ИмяАгента, ПарольАгента, ИмяАдминистратора, ПарольАдминистратора и числовой НомерСеанса. Для полей паролей включите режим пароля, не сохраняйте значения в настройках формы.

  5. КлючКластера вручную возьмите из собственной консоли администрирования: имя кластера|имя сервера|основной порт, например Учебный|localhost|1541. Это порт кластера, не порт агента 1540 и не порт RAS 1545.

  6. Серверный код связывается только с агентом 127.0.0.1:1540 на том Windows-сервере, где исполняется модуль. Вводятся существующие учебные учётные данные агента и кластера; права и пароли не изменяются.

  7. Клиентский обработчик приведён полностью: он очищает поля паролей до вызова сервера и не печатает аргументы или технический текст ошибок. Это не гарантирует безопасное стирание строк из памяти; учебные учётные данные не должны сохраняться в настройках формы.

  8. Сначала НомерСеанса = 0: получите только ID и AppID сеансов этой учебной базы. Затем введите один ID из этого списка. ID уникален внутри информационной базы, а не во всём кластере.

  9. Ниже дан законченный серверный пример получения настоящего объекта Сеанс, а не функция, требующая неизвестный ИсходныйОбъект. COM и кластер при подготовке руководства не запускались; требуется ручной запуск на собственном стенде.

&НаКлиенте
Процедура Прочитать(Команда)
    ЛокальныйПарольАгента = ПарольАгента;
    ЛокальныйПарольАдминистратора = ПарольАдминистратора;
    ПарольАгента = "";
    ПарольАдминистратора = "";
    Попытка
        Отчет = ПрочитатьУчебныйСеанс(КлючКластера, ИмяАгента, ЛокальныйПарольАгента, ИмяАдминистратора, ЛокальныйПарольАдминистратора, НомерСеанса);
    Исключение
        ЛокальныйПарольАгента = "";
        ЛокальныйПарольАдминистратора = "";
        Сообщить("Чтение не выполнено. Проверьте собственный стенд, COM, ключ кластера, права и наличие выбранного сеанса. Технические сведения проверяет администратор стенда.");
        Возврат;
    КонецПопытки;
    ЛокальныйПарольАгента = "";
    ЛокальныйПарольАдминистратора = "";
    Сообщить(Отчет);
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПрочитатьУчебныйСеанс(КлючКластера, ИмяАгента, ПарольАгента, ИмяАдминистратора, ПарольАдминистратора, НомерСеанса)
    Если ПустаяСтрока(КлючКластера) Тогда
        ВызватьИсключение "Укажите точный ключ собственного тестового кластера";
    КонецЕсли;
    Если НомерСеанса < 0 Или Цел(НомерСеанса) <> НомерСеанса Тогда
        ВызватьИсключение "Номер сеанса должен быть целым неотрицательным числом";
    КонецЕсли;
    Соединитель = Новый COMОбъект("V85.COMConnector");
    Агент = Соединитель.ConnectAgent("127.0.0.1:1540");
    Агент.AuthenticateAgent(ИмяАгента, ПарольАгента);
    ПодходящиеКластеры = Новый Массив;
    Для Каждого Кандидат Из Агент.GetClusters() Цикл
        КлючКандидата = СтрШаблон("%1|%2|%3", Кандидат.ClusterName, Кандидат.HostName, Кандидат.MainPort);
        Если НРег(КлючКандидата) = НРег(КлючКластера) Тогда
            ПодходящиеКластеры.Добавить(Кандидат);
        КонецЕсли;
    КонецЦикла;
    Если ПодходящиеКластеры.Количество() <> 1 Тогда
        ВызватьИсключение "Собственный тестовый кластер не выбран однозначно";
    КонецЕсли;
    Кластер = ПодходящиеКластеры.Получить(0);
    Агент.Authenticate(Кластер, ИмяАдминистратора, ПарольАдминистратора);
    УчебныеБазы = Новый Массив;
    Для Каждого ОписаниеБазы Из Агент.GetInfoBases(Кластер) Цикл
        Если ОписаниеБазы.Name = "guide-owned-session-lab" Тогда
            УчебныеБазы.Добавить(ОписаниеБазы);
        КонецЕсли;
    КонецЦикла;
    Если УчебныеБазы.Количество() <> 1 Тогда
        ВызватьИсключение "Зарегистрированная учебная база не выбрана однозначно";
    КонецЕсли;
    УчебнаяБаза = УчебныеБазы.Получить(0);
    УчебныеСеансы = Агент.GetInfoBaseSessions(Кластер, УчебнаяБаза);
    СтрокиОтчета = Новый Массив;
    НайденныеСеансы = Новый Массив;
    Для Каждого КандидатСеанс Из УчебныеСеансы Цикл
        Если НомерСеанса = 0 Тогда
            СтрокиОтчета.Добавить(СтрШаблон("Сеанс %1; приложение %2", КандидатСеанс.SessionID, КандидатСеанс.AppID));
        ИначеЕсли КандидатСеанс.SessionID = НомерСеанса Тогда
            НайденныеСеансы.Добавить(КандидатСеанс);
        КонецЕсли;
    КонецЦикла;
    Если НомерСеанса = 0 Тогда
        Если СтрокиОтчета.Количество() = 0 Тогда
            Возврат "В учебной базе сейчас нет сеансов";
        КонецЕсли;
        Возврат СтрСоединить(СтрокиОтчета, Символы.ПС);
    КонецЕсли;
    Если НайденныеСеансы.Количество() <> 1 Тогда
        ВызватьИсключение "Учебный сеанс исчез или не выбран однозначно; обновите список";
    КонецЕсли;
    Сеанс = НайденныеСеансы.Получить(0);
    Если Сеанс.InfoBase.Name <> "guide-owned-session-lab" Тогда
        ВызватьИсключение "Сеанс не принадлежит выбранной учебной базе";
    КонецЕсли;
    БлокировщикСУБД = Сеанс.blockedByDBMS;
    БлокировщикМенеджера = Сеанс.blockedByLS;
    СтрокиОтчета.Добавить(СтрШаблон("ID блокировщика СУБД=%1; ID блокировщика менеджера=%2", БлокировщикСУБД, БлокировщикМенеджера));
    СтрокиОтчета.Добавить(СтрШаблон("Блокировка СУБД отсутствует=%1; блокировка менеджера отсутствует=%2", БлокировщикСУБД = 0, БлокировщикМенеджера = 0));
    ЗахватЕсть = Не ПустаяСтрока(Сеанс.dbProcInfo);
    СтрокиОтчета.Добавить(СтрШаблон("Соединение СУБД захвачено=%1; с момента захвата, мс=%2", ЗахватЕсть, Сеанс.dbProcTook));
    Если ЗахватЕсть Тогда
        СтрокиОтчета.Добавить(СтрШаблон("Момент последнего захвата=%1", Сеанс.dbProcTookAt));
    КонецЕсли;
    СтрокиОтчета.Добавить(СтрШаблон("Сервисный вызов указан=%1", Не ПустаяСтрока(Сеанс.CurrentServiceName)));
    Возврат СтрСоединить(СтрокиОтчета, Символы.ПС);
КонецФункции

Разбор по шагам

  1. Ноль в blockedByDBMS/blockedByLS означает отсутствие соответствующего блокировщика. Ненулевое число — ID блокирующего сеанса, не время и не число блокировок.

  2. dbProcInfo содержит номер соединения в терминах СУБД; это не SQL запрос и не стек. Его содержимое не выводим.

  3. dbProcTook — миллисекунды с захвата соединения, не доказательство, что весь интервал выполнялся запрос. Транзакция и временные таблицы тоже могут удерживать соединение.

  4. dbProcTookAt — момент последнего захвата. При отсутствии захвата не представляем его как активную работу.

  5. CurrentServiceName читаем только как признак текущего сервисного вызова; отчёт не вмешивается в работу.

Как проверить результат

  1. На свободном учебном клиенте нули и Ложь для захвата допустимы; не создавайте искусственную блокировку в рабочей базе.

  2. Поля явно подписаны ID и мс; отсутствуют команды отключения клиентов или удаления соединений.

Ожидаемый результат

Получен безопасный диагностический отчёт, который не смешивает идентификаторы и время.

На что обратить внимание

  1. Ненулевой dbProcTook не означает зависший SQL. Для причины нужен отдельный анализ на стенде.

  2. Блокировка может исчезнуть между чтениями. Один снимок не доказывает длительность проблемы.

  3. Нельзя завершать найденный ID в другой базе: SessionID не является глобальным номером кластера.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.