Что делать, если не удается получить или удалить элемент справочника из-за ошибки «Соединение не удерживается сервером»?

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

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

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

Причины возникновения проблемы

Сбой происходит при попытке вызова метода ПолучитьОбъект() или использовании явного удаления через объект УдалениеОбъекта:


// Примеp кода, вызывающего сбой при битых данных:
Удаление = Новый УдалениеОбъекта(Ссылка);
Удаление.Записать();

Выясним, почему это происходит:

  1. Повреждение LOB/BLOB-страниц на уровне СУБД: Картинки, файлы и произвольные двоичные данные хранятся в типе реквизита ХранилищеЗначения. В СУБД (например, MS SQL Server) эти данные размещаются в специальных бинарных структурах (LOB-страницах). При физических сбоях дисковой подсистемы, аварийном перезапуске сервера или сбоях питания структура этих страниц может повредиться.
  2. Особенности работы метода ПолучитьОбъект(): В отличие от чтения отдельных реквизитов через запрос или получения ссылки, метод ПолучитьОбъект() полностью считывает из базы всю строку таблицы со всеми хранилищами значений. При попытке прочитать битый бинарный блок драйвер СУБД или рабочий процесс 1С (rphost) сталкивается с необрабатываемым исключением.
  3. Аварийное завершение процесса: Так как сбой происходит на уровне работы СУБД и низкоуровневого кода платформы, конструкция Попытка ... Исключение не помогает — рабочий процесс rphost аварийно завершается, и клиентский сеанс теряет связь с сервером.

Способ 1. Проверка и исправление таблицы на уровне СУБД (Рекомендуемый)

Если проблема вызвана битыми бинарными страницами в MS SQL Server, наиболее эффективным решением является проверка и восстановление целостности конкретной таблицы СУБД.

Разберем порядок действий:

  1. Определим имя таблицы СУБД, соответствующей справочнику. Это можно сделать через функцию конфигуратора ПолучитьСтруктуруХраненияБазыДанных() или обработку «Структура хранения базы данных».
  2. В среде управления MS SQL Server Management Studio (SSMS) выполним проверку целостности таблицы командой CHECKTABLE:
    
    DBCC CHECKTABLE ('_Reference123'); -- Укажите реальное имя таблицы из структуры хранения
    
  3. Если команда обнаружить ошибки структуры LOB-страниц, необходимо выполнить полную проверку базы данных командой DBCC CHECKDB с параметрами исправления (потребуется перевод базы в монопольный режим):
    
    ALTER DATABASE [Имя_Базы] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    DBCC CHECKDB ('Имя_Базы', REPAIR_ALLOW_DATA_LOSS);
    ALTER DATABASE [Имя_Базы] SET MULTI_USER;
    

После успешного исправления структуры LOB-страниц на стороне СУБД обращение к объекту ПолучитьОбъект() перестанет вызывать падение рабочего процесса.

Способ 2. Штатное тестирование и исправление (ТИИ)

Если нет возможности работать напрямую с СУБД, рассмотрим вариант выполнения штатных процедур платформы 1С:

  1. Создадим полную резервную копию базы данных (DT-файл или средствами СУБД).
  2. Завершим все активные сеансы пользователей и остановим службы фоновых заданий.
  3. Запустим Конфигуратор и откроем меню Администрирование > Тестирование и исправление...
  4. Установим флаги:
    • Проверка ссылочной целостности;
    • Проверка логической целостности.
  5. Выберем режим «Удалять объект» или «Очищать ссылки» при обнаружении ошибок.

Способ 3. Очистка поврежденного реквизита через прямой SQL-запрос

Если битая картинка не представляет ценности, но сам элемент справочника удалять нельзя, можно обнулить поле с хранилищем значений прямо в СУБД:

  1. Узнаем имя поля с хранилищем значений и внутренний идентификатор ссылки (_IDRRef).
  2. Выполним запрос обновления поля в нулевое значение (`NULL` или пустой массив `0x`):
    
    UPDATE _Reference123
    SET _Fld456 = 0x
    WHERE _IDRRef = 0x80C100155D010B0111E2A3C4D5E6F700;
    
  3. После обнуления поврежденных данных перезапустим рабочий процесс 1С (или очистим кэш сервера). Метод ПолучитьОбъект() снова начнет корректно считывать объект.

Важно: Любые операции с принудительным выполнением SQL-запросов и исправлением структуры таблиц должны производиться только при наличии свежей резервной копии и при полном отсутствии активных пользователей в базе.

← На главную