При переводе старых конфигураций (таких как «Бухгалтерия предприятия 1.6», «Управление торговлей 10.3» и других нетиповых решений) с платформы 1С 8.2 на платформу 8.3 пользователи и администраторы часто сталкиваются с аварийным завершением работы. В журнале регистрации и на экранах клиентов появляется ошибка СУБД: «Microsoft SQL Native Client: В базе данных уже существует объект с именем "#tt1" (или "##tt...") HRESULT=80040E14, native=2714». Ошибка может возникать хаотично: при проведении документов, формировании отчетов, динамическом обновлении или попытке выполнить тестирование и исправление информационной базы.
Разберем детально механизм появления этого сбоя, выясним его корень и рассмотрим пошаговые способы полного устранения проблемы.
Символ # в MS SQL Server обозначает локальную временную таблицу, создаваемую в системной базе tempdb в рамках текущей пользовательской сессии (SPID). Платформа 1С транслирует запросы с созданием временных таблиц, присваивая им системные имена вида #tt1, #tt2 и так далее.
Проанализируем цепочку событий, приводящую к конфликту имен:
rphost держит пул открытых физических соединений к MS SQL Server. Если клиентский сеанс прерывается, запрос падает по таймауту или пользователь аварийно закрывает программу, физическое подключение возвращается в пул сервера 1С.sp_reset_connection не отрабатывает должным образом. В результате таблица #tt1 продолжает существовать внутри конкретного соединения.#tt1, на что MS SQL Server возвращает ошибку 2714 (объект с таким именем уже существует).#tt не только при явном использовании менеджера временных таблиц, но и при передаче списков значений в конструкции вида ГДЕ Поле В (&Массив), а также при работе отборов динамических списков.Как показывает практика, перевод конфигурации с устаревшего режима совместимости решает проблему без возврата на старые платформы. Режим совместимости с версией 8.1 в среде 8.3 официально считается устаревшим и провоцирует рассинхронизацию с пулом соединений.
Разберем по шагам, как правильно переключить режим:
Версия 8.1 на Версия 8.2.13 или Версия 8.2.16.Обратим внимание на нюансы, которые могут возникнуть после изменения режима совместимости:
ПроверкаЗаполнения. Если в метаданных было установлено значение Выдавать ошибку (например, для наименования), программа начнет жестко требовать заполнение поля при записи. При необходимости скорректируйте это свойство на Не проверять.УПОРЯДОЧИТЬ ПО используются поля, которых нет в списке выборки ВЫБРАТЬ, платформа может вызвать исключение.ОбработкаЗаполнения, поведение которой в 8.1 могло игнорироваться.Если ошибка возникает в конкретной операции (например, при проведении определенного документа или формировании тяжелого отчета), причиной часто является передача больших списков в параметр условия В (...). Платформа 1С автоматически пытается создать таблицу #tt1 на стороне SQL Server, выгрузить туда переданный массив и выполнить подзапрос.
Посмотрим на пример проблемного кода:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка,
| Номенклатура.Артикул
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Ссылка В(&МассивСсылок)";
Запрос.УстановитьПараметр("МассивСсылок", МассивНоменклатуры);
Результат = Запрос.Выполнить();
Если МассивНоменклатуры содержит сотни или тысячи элементов, при сбое транзакции созданная СУБД таблица #tt1 рискует зависнуть в соединении. Перепишем логику с использованием объекта МенеджерВременныхТаблиц и явным уничтожением созданных структур:
МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
// Помещаем массив в типизированную таблицу значений
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Ссылка", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
Для Каждого ТекСсылка Из МассивНоменклатуры Цикл
Стр = ТЗ.Добавить();
Стр.Ссылка = ТекСсылка;
КонецЦикла;
Запрос.Текст =
"ВЫБРАТЬ
| ТаблицаИсточника.Ссылка КАК Ссылка
|ПОМЕСТИТЬ ВТ_Фильтр
|ИЗ
| &ТаблицаИсточника КАК ТаблицаИсточника
|ИНДЕКСИРОВАТЬ ПО
| Ссылка;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Номенклатура.Ссылка,
| Номенклатура.Артикул
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Фильтр КАК ВТ_Фильтр
| ПО Номенклатура.Ссылка = ВТ_Фильтр.Ссылка;
|
|////////////////////////////////////////////////////////////////////////////////
|УНИЧТОЖИТЬ ВТ_Фильтр";
Запрос.УстановитьПараметр("ТаблицаИсточника", ТЗ);
Результат = Запрос.Выполнить();
// Обязательно закрываем менеджер для освобождения ресурсов
МенеджерВТ.Закрыть();
Использование конструкции УНИЧТОЖИТЬ в теле запроса и метода Закрыть() у объекта МенеджерВременныхТаблиц гарантирует очистку временных объектов на стороне SQL-сервера сразу после завершения работы алгоритма.
Сбой генерации временных таблиц являлся зарегистрированной ошибкой в некоторых релизах платформ веток 8.3.6 (например, 8.3.6.2332, 8.3.6.2390) и ранних сборках 8.3.7. Если специфика конфигурации категорически не позволяет повысить режим совместимости до 8.2, проанализируем варианты смены версии платформы:
#tt1.Чтобы исключить накопление зависших соединений в процессах rphost, скорректируем параметры кластера через консоль администрирования 1С:
86400 секунд (сутки) или чаще, если нагрузка высокая. Это позволит автоматически перезапускать рабочие процессы без разрыва пользовательских сессий, очищая внутренние пулы подключений.Дополнительно убедимся в корректности окружения со стороны СУБД:
SQL Server Native Client 10.0 (от SQL Server 2008), установим Microsoft SQL Server 2012 Native Client (версия 11.0). Более свежий драйвер корректнее транслирует служебные команды управления сессиями.tempdb разбита на несколько файлов данных одинакового размера (по числу физических ядер процессора, но не более 8). Зададим фиксированный автоприрост файлов (например, по 512 МБ), исключив процентное приращение, чтобы избежать задержек при распределении страниц для таблиц #tt.