Почему блокировка начала сеансов в консоли сервера 1С не срабатывает в самописной конфигурации?

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

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

Платформенная и программная блокировка сеансов: в чем разница?

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

  1. Платформенная блокировка. Эта блокировка устанавливается непосредственно через консоль сервера 1С:Предприятия. Она является базовым механизмом и предназначена для предотвращения запуска новых сеансов пользователями. При установке такой блокировки, мы можем задать:

    • Сообщение для пользователей, которое будет выводиться при попытке входа.

    • Период действия блокировки, задавая время начала и окончания.

    • Специальный "код разрешения", который позволяет администраторам войти в базу даже во время действия блокировки. Для этого необходимо запустить 1С с параметром /UC <код разрешения>.

    • Возможность блокировки регламентных и фоновых заданий.

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

  2. Программная блокировка. Это дополнительный уровень контроля, который реализуется непосредственно в коде конфигурации 1С. Платформа 1С предоставляет для этого специальный объект БлокировкаСеансов и глобальные функции УстановитьБлокировкуСеансов() и ПолучитьБлокировкуСеансов(). Эти механизмы позволяют нам:

    • Получать текущее состояние блокировки, установленной через консоль сервера.

    • Программно управлять блокировкой из кода конфигурации.

    • Реализовывать более сложную логику, например, принудительное завершение активных сеансов, вывод дополнительных предупреждений или выполнение специфических действий при наступлении блокировки.

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

Как типовые конфигурации 1С обрабатывают блокировку?

Для того чтобы блокировка начала сеансов работала надежно, типовые конфигурации 1С, такие как ЗУП 3.1, УПП и другие, содержат встроенный код, который обрабатывает состояние платформенной блокировки. Этот код не просто констатирует факт блокировки, а активно реагирует на него, завершая сеансы пользователей и предотвращая запуск новых, если у пользователя нет достаточных прав или специального кода разрешения.

Обратимся к примеру из типовой конфигурации, который был упомянут в обсуждении. Мы видим, как функция РазрешитьРаботуПользователей() (или аналогичная) может обрабатывать состояние блокировки:


Функция РазрешитьРаботуПользователей() Экспорт
    
    Если НЕ ПравоДоступа("Администрирование", Метаданные) Тогда
        Возврат Ложь;
    КонецЕсли;
    
    ТекущийРежим = ПолучитьБлокировкуСеансов();
    Если ТекущийРежим.Установлена Тогда
        НовыйРежим = Новый БлокировкаСеансов;
        НовыйРежим.Установлена = Ложь;
        УстановитьБлокировкуСеансов(НовыйРежим);
    КонецЕсли;
    Возврат Истина;
    
КонецФункции

Давайте проанализируем этот код:

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

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

  3. Обработка установленной блокировки: Если ТекущийРежим.Установлена истина (то есть блокировка активна), то в данном конкретном примере (который, возможно, является частью логики снятия блокировки или предоставления административного доступа) происходит снятие программной блокировки для данного сеанса администратора. Это демонстрирует, что конфигурация активно взаимодействует с состоянием блокировки.

В более полной логике, используемой в типовых конфигурациях для предотвращения входа обычных пользователей, эта функция (или аналогичные механизмы в обработчиках типа ПриНачалеРаботыСистемы или ОбработкаПроверкиЗаполнения) будет проверять ТекущийРежим.Установлена. Если блокировка активна и у пользователя нет административных прав или введенного кода разрешения, система не позволит ему войти, а в случае уже активного сеанса может принудительно завершить его или вывести предупреждение.

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

Почему блокировка может не срабатывать в вашей самописной базе?

Теперь, когда мы понимаем разницу между платформенной и программной блокировкой, становится очевиднее, почему в самописной конфигурации блокировка может не работать так, как ожидается. Основная причина заключается в том, что ваша конфигурация, скорее всего, не содержит кода, который бы "подхватывал" платформенную блокировку и обеспечивал ее выполнение на уровне приложения. Давайте выясним более конкретные потенциальные причины:

  1. Отсутствие обработки в коде конфигурации: Это наиболее вероятная причина. В вашей самописной базе нет специальных процедур или функций, которые бы проверяли состояние объекта БлокировкаСеансов при попытке пользователя войти в систему или во время его работы. Следовательно, конфигурация просто не знает, как реагировать на установленную через консоль сервера блокировку.

  2. "Зависшие" сеансы: Даже если вы установили блокировку, в базе могут оставаться активные, но "зависшие" или некорректно завершенные сеансы. Такие сеансы могут мешать корректной работе блокировки. Их необходимо принудительно завершать через консоль кластера серверов 1С.

  3. Внешние соединения (COM, API и прочие): Для некоторых типов внешних соединений (например, через COM-объекты, HTTP-сервисы, веб-сервисы) платформа может не применять блокировку по умолчанию. Если ваша самописная конфигурация активно использует такие соединения, и в ней нет логики для их обработки при блокировке, то они будут продолжать работать.

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

  5. Некорректное "Внешнее управление сеансами" (CORP лицензия): Если в свойствах информационной базы включена опция "Внешнее управление сеансами", но при этом отсутствует соответствующая CORP-лицензия, это может привести к ошибкам и некорректной работе блокировки и других функций управления сеансами.

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

Решение проблемы: Шаги по реализации корректной блокировки в самописной конфигурации

Чтобы блокировка начала сеансов работала в вашей самописной конфигурации так же эффективно, как в типовой ЗУП 3.1, мы рекомендуем выполнить следующие шаги. Наша цель — дополнить платформенную блокировку программной логикой, которая будет обеспечивать ее надежное применение.

  1. Анализ типовых конфигураций (ЗУП 3.1, УПП)

    Начнем с изучения того, как реализована обработка блокировки в стандартных конфигурациях 1С. Мы не будем просто копировать код, но почерпнем идеи и лучшие практики. Откройте конфигурацию ЗУП 3.1 (или УПП) в режиме конфигуратора и выполните поиск по строке "БлокировкаСеансов". Обратите внимание на общие модули, модули управляемого приложения или модуля сеанса. Вас интересуют:

    • Функции, подобные РазрешитьРаботуПользователей() или ПроверитьБлокировкуСеансов().

    • Места, где вызываются функции ПолучитьБлокировкуСеансов() и УстановитьБлокировкуСеансов().

    • Механизмы, которые проверяют код разрешения для администраторов (параметр запуска /UC).

    • Логика завершения активных сеансов, если таковая присутствует.

    Изучите, где и когда происходят эти проверки. Часто это делается при старте системы, а также в некоторых длительных операциях или обработчиках ожидания, чтобы обеспечить завершение работы пользователей, которые уже были в системе.

  2. Реализация программной обработки блокировки в вашей самописной конфигурации

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

    Где разместить код:

    • Модуль управляемого приложения: Это идеальное место для проверки при старте системы. Например, в обработчике ПриНачалеРаботыСистемы().

    • Общий модуль (клиент/сервер): Создайте отдельный общий модуль (с опциями "Сервер" и "Клиент (обычное приложение)" / "Клиент (управляемое приложение)" в зависимости от потребностей), в котором будут собраны функции для работы с блокировкой.

    Что должен делать код:

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

      
      // Пример кода в модуле управляемого приложения или общем модуле
      Процедура ПриНачалеРаботыСистемы()
          ПроверитьБлокировкуСеансовИПринятьМеры();
      КонецПроцедуры
      
      Процедура ПроверитьБлокировкуСеансовИПринятьМеры() Экспорт
          Перем Отказ;
          ТекущийРежимБлокировки = ПолучитьБлокировкуСеансов();
          Если ТекущийРежимБлокировки.Установлена Тогда
              // Проверяем, является ли текущий пользователь администратором
              // или введен ли код разрешения
              Если Не ПравоДоступа("Администрирование", Метаданные) ИЛИ
                 Не ПроверитьКодРазрешения(ТекущийРежимБлокировки.КодРазрешения) Тогда // Реализуйте ПроверитьКодРазрешения
                  Сообщить(ТекущийРежимБлокировки.Сообщение); // Выводим сообщение для пользователя
                  ВызватьИсключение "База данных временно недоступна для обычных пользователей."; // Предотвращаем вход
              КонецЕсли;
          КонецЕсли;
      КонецПроцедуры
      
      // Пример функции ПроверитьКодРазрешения - требует доработки в зависимости от вашей логики
      Функция ПроверитьКодРазрешения(КодИзБлокировки)
          // Получаем параметры запуска
          ПараметрыЗапуска = СтрРазделить(ПараметрыЗапускаКлиента(), " ", Ложь);
          Для Каждого Параметр Из ПараметрыЗапуска Цикл
              Если НачинаетсяС(Нрег(Параметр), "/uc") Тогда
                  ПользовательскийКод = СтрЗаменить(Нрег(Параметр), "/uc", "");
                  Возврат ПользовательскийКод = Нрег(КодИзБлокировки);
              КонецЕсли;
          КонецЦикла;
          Возврат Ложь;
      КонецФункции
      

      Важно: Функция ПроверитьКодРазрешения в примере является упрощенной и требует доработки. Более надежный способ получения кода разрешения — это использование функций работы с параметрами командной строки или, если вы на платформе 8.3.14+, объект ПараметрыКлиентскогоПриложения.

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

  3. Принудительное завершение активных сеансов вручную

    На этапе внедрения новой логики или при возникновении "зависших" сеансов, всегда оставайтесь в готовности принудительно завершить сеансы через консоль кластера серверов 1С. Мы открываем консоль, находим нашу информационную базу, переходим на вкладку "Сеансы", выделяем все ненужные сеансы и нажимаем кнопку "Завершить сеанс". Это гарантирует, что все пользователи будут отключены, пока вы тестируете или внедряете изменения.

  4. Учет особенностей внешних соединений

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

  5. Использование кода разрешения для администраторов

    Убедимся, что ваша конфигурация корректно обрабатывает параметр запуска /UC <код разрешения>. Это критически важно для того, чтобы вы, как администратор, могли войти в базу и выполнить необходимые работы, даже когда для остальных пользователей действует блокировка. Логика, которую мы рассматривали выше в функции ПроверитьКодРазрешения(), должна быть тщательно проработана.

  6. Дополнительные проверки (файл 1Cv8.cdn, лицензии)

    В случае стойких и необъяснимых проблем, проверим следующее:

    • Файл 1Cv8.cdn: Если информационная база файловая или вы подозреваете проблемы с кэшем, можно попробовать удалить этот файл из каталога базы данных (после предварительного полного завершения всех сеансов и остановки сервера 1С, если применимо). В клиент-серверном варианте этот файл находится в каталоге сервера 1С и управляется платформой.

    • Внешнее управление сеансами (CORP лицензия): Убедимся, что опция "Внешнее управление сеансами" в свойствах информационной базы не включена без наличия соответствующей CORP-лицензии. Это может вызывать непредсказуемое поведение.

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

← На главную