При работе с расширениями в среде 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда привычные механизмы обновления ведут себя иначе, чем при редактировании основной конфигурации. Одной из таких проблем является отсутствие диалогового окна «Завершить работу пользователей» при попытке обновить базу данных после внесения изменений в структуру расширения. Вместо удобного предложения выгнать всех из базы система выдает жесткую ошибку: «Ошибка разделенного доступа к базе данных». Проанализируем, почему так происходит, и как с этим бороться.
Первым делом нам необходимо обратить внимание на версию платформы. Как показывает практика и официальные списки изменений, поведение системы при обновлении расширений существенно зависит от установленного релиза. В ветке 8.3.22 (например, в популярном релизе 8.3.22.2239) механизмы блокировки сеансов для расширений были реализованы не полностью симметрично основной конфигурации.
Когда мы меняем структуру основной базы (добавляем справочник, реквизит или меняем тип данных), конфигуратор понимает, что требуется монопольный доступ. Если в базе есть активные сеансы (Тонкий клиент, Толстый клиент или Веб-клиент), платформа инициирует стандартный механизм вытеснения пользователей. Однако в версии 8.3.22 при изменении метаданных расширения, которые влекут за собой создание или изменение физических таблиц в СУБД, этот триггер срабатывает не всегда.
Проанализируем ситуацию: платформа видит конфликт на уровне СУБД (таблицы расширения заблокированы текущими сессиями), но обработчик, отвечающий за вывод кнопки «Завершить работу пользователей», не получает управление. В итоге мы получаем простое сообщение об ошибке блокировки без возможности автоматизированного решения проблемы прямо из Конфигуратора.
Рассмотрим подробнее, какие именно изменения вызывают блокировку. Важно помнить, что расширение может просто дополнять логику (код в модулях), а может изменять структуру данных. Если в свойствах расширения установлена галочка «Данные хранятся в расширении», и вы добавили новый реквизит или объект, 1С создает в базе данных реальные таблицы (обычно они имеют префиксы вида _InfoRgED... или аналогичные).
Если пользователь в данный момент работает с объектом, который заимствован в расширение, или если расширение активно используется в его сеансе, СУБД накладывает блокировку на соответствующие структуры. В старых релизах платформы механизм «мягкого» завершения работы просто «не знал», что блокировка вызвана именно таблицами расширения, и считал это неустранимой ошибкой доступа.
Разберем, как ситуация изменилась в более новых версиях. Начиная с версии 8.3.23, разработчики 1С синхронизировали логику обновления расширений с логикой обновления основной конфигурации. Теперь при обнаружении активных соединений, мешающих обновлению БД расширения, платформа корректно выводит знакомое окно с предложением завершить сеансы.
Рассмотрим шаги для исправления ситуации:
8.3.22, оптимальным решением будет переход на актуальный релиз ветки 8.3.23 или выше.Посмотрим, как мы можем принудительно освободить базу для обновления расширения, если кнопка в Конфигураторе отсутствует. Рассмотрим два основных способа.
Способ 1. Использование консоли администрирования кластера (MMC)
Это самый надежный метод для клиент-серверного варианта работы. Выполним следующие действия:
Кластеры -> Ваш сервер -> Информационные базы.Сеансы.Способ 2. Программное завершение сеансов через код
Иногда полезно иметь под рукой скрипт, который поможет быстро очистить базу. Рассмотрим пример кода, который можно использовать во внешней обработке для программного отключения пользователей (требуются права администратора):
// Пример программного завершения сеансов
Процедура ЗавершитьРаботуВсехПользователей()
// Устанавливаем блокировку соединений
Блокировка = Новый БлокировкаУстановкиСоединений;
Блокировка.Установлена = Истина;
Блокировка.Начало = ТекущаяДата();
Блокировка.Конец = ТекущаяДата() + 300; // на 5 минут
Блокировка.Сообщение = "Выполняется обновление расширения базы данных. Пожалуйста, подождите.";
Блокировка.КодРазрешения = "UpdateKey";
УстановитьБлокировкуУстановкиСоединений(Блокировка);
// Получаем список активных сеансов и завершаем их
Сеансы = ПолучитьСеансыИнформационнойБазы();
Для Каждого ТекущийСеанс Из Сеансов Цикл
Если ТекущийСеанс.НомерСеанса <> НомерСеанса() Тогда
ЗавершитьСеанс(ТекущийСеанс);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Часто причиной «глухой» блокировки, которую не видит стандартный механизм выгона, являются Фоновые задания. В отличие от активных пользователей в Тонком клиенте, фоновые задания могут запускаться планировщиком автоматически каждую минуту. Даже если вы выгнали всех пользователей, задание может успеть стартовать в промежутке между нажатием кнопки «Обновить» и фактической блокировкой таблиц.
Рассмотрим, как бороться с фоновыми заданиями:
Блокировки. Если там висит активное соединение Background job, его нужно удалить вручную.Еще один важный момент, который стоит проанализировать — включенная HTTP-отладка или отладка через tcp. В платформе 8.3.22 был зафиксирован баг, когда отладочные сессии блокировали метаданные расширения, но не классифицировались системой как сеансы, подлежащие штатному завершению. Если вы столкнулись с ошибкой доступа, попробуйте временно отключить отладку на сервере приложений (параметр -debug в строке запуска службы ragent) и перезапустить службу.
Подводя итог нашему исследованию, можно сделать следующие выводы:
8.3.22.Сеансов и Блокировок перед обновлением структуры расширения.Следуя этим рекомендациям, мы сможем избежать ошибок разделенного доступа и обеспечить стабильную разработку и внедрение расширений в систему 1С.