К статье
Практический материал

Разработка и Конфигурация · 9 мин

Временная таблица в 1С: когда она уничтожается

Когда уничтожается временная таблица в 1С: время жизни менеджера временных таблиц, команда УНИЧТОЖИТЬ, типичные ошибки и рекомендации по очистке памяти.

Временная таблица в 1С живёт не дольше, чем менеджер временных таблиц, которому она принадлежит. Это ключевое правило: как только объект МенеджерВременныхТаблиц выходит из области видимости и уничтожается сборщиком мусора платформы, все его временные таблицы удаляются автоматически. Явно удалить таблицу раньше можно командой запроса УНИЧТОЖИТЬ ИмяТаблицы.

На практике время жизни зависит от того, где создан менеджер: локальная переменная процедуры, реквизит объекта (обработки, отчёта), параметр запроса или менеджер, созданный платформой неявно. От этого зависит, «протухнет» ли таблица сразу после выполнения процедуры или будет висеть в памяти сервера до закрытия формы.

Понимание жизненного цикла важно по двум причинам. Первая — память: большие временные таблицы на сервере 1С или в СУБД (временные таблицы SQL Server / PostgreSQL) могут заметно нагружать систему, если их не очищать. Вторая — корректность: попытка обратиться к таблице, которая уже уничтожена, вызывает ошибку «Таблица не найдена».

Что определяет время жизни временной таблицы

Каждая временная таблица, созданная конструкцией ПОМЕСТИТЬ ИмяТаблицы, привязана к конкретному экземпляру менеджера временных таблиц. Пока менеджер существует — таблица доступна для последующих запросов, использующих тот же менеджер. Как только менеджер уничтожен, платформа удаляет все его таблицы.

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

Сценарий 1: менеджер не задан явно

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

Практическое следствие: нельзя выполнить первым запросом ПОМЕСТИТЬ, а вторым, отдельным объектом запроса без менеджера, прочитать эту таблицу — получите ошибку, что таблица не найдена. Либо объединяйте тексты в один пакет, либо передавайте общий менеджер обоим запросам.

Сценарий 2: менеджер — локальная переменная процедуры

МенеджерВТ = Новый МенеджерВременныхТаблиц;

Запрос = Новый Запрос;

Запрос.МенеджерВременныхТаблиц = МенеджерВТ;

Запрос.Текст = "ВЫБРАТЬ ... ПОМЕСТИТЬ ВТ_Данные";

Запрос.Выполнить();

В этом варианте таблица ВТ_Данные живёт, пока жива переменная МенеджерВТ. При выходе из процедуры переменная теряет последнюю ссылку, менеджер уничтожается, и таблица удаляется автоматически. Дополнительных действий от разработчика не требуется — это самый безопасный и предсказуемый сценарий.

Нюанс: если процедура серверная и вызывается многократно в цикле, каждый вызов создаёт новый менеджер и новые таблицы. Старые уничтожаются при выходе из предыдущей итерации, поэтому утечки нет, но лучше выносить создание менеджера за пределы цикла и очищать таблицы командой УНИЧТОЖИТЬ между итерациями — так меньше нагрузка на СУБД.

Сценарий 3: менеджер в реквизите объекта

Когда менеджер хранится в реквизите обработки, отчёта или формы, временные таблицы живут столько, сколько живёт сам объект. Для формы — до её закрытия, для объекта обработки — пока существует экземпляр. Это удобно для многоэтапных алгоритмов, где промежуточные данные нужны в разных процедурах.

Опасность сценария — накопление таблиц. Если в течение жизни формы создаются десятки временных таблиц с большим объёмом данных, вся эта память удерживается до закрытия формы. Рекомендуется явно уничтожать таблицы, которые больше не нужны.

Явное уничтожение командой УНИЧТОЖИТЬ

Команда УНИЧТОЖИТЬ ИмяТаблицы удаляет таблицу из менеджера немедленно, не дожидаясь конца его жизни. Синтаксис простой:

Запрос.Текст = "УНИЧТОЖИТЬ ВТ_Данные";

Запрос.Выполнить();

Команду можно включать в пакетный запрос последним шагом — тогда очистка происходит в том же обращении к серверу. Также в языке запросов доступна конструкция УНИЧТОЖИТЬ внутри пакета после последнего использования таблицы, что считается хорошим тоном при работе с большими выборками.

Порядок безопасной работы с временными таблицами
  1. 1
    Создайте менеджер временных таблиц явно и назначьте его всем запросам цепочки
  2. 2
    Помещайте промежуточные данные через ПОМЕСТИТЬ и используйте их в последующих запросах того же менеджера
  3. 3
    После последнего использования добавьте в пакет команду УНИЧТОЖИТЬ для каждой крупной таблицы
  4. 4
    Не сохраняйте менеджер в долгоживущие реквизиты без необходимости
  5. 5
    Проверьте в отладчике, что обращений к таблице после её уничтожения нет

Временные таблицы на стороне СУБД

В клиент-серверном режиме временные таблицы 1С физически создаются как временные таблицы СУБД (например, в tempdb для MS SQL Server) в рамках соединения. Пока соединение с СУБД удерживается сеансом или пулом соединений, таблица существует физически, даже если платформа уже «забыла» про неё логически.

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

Типичные ошибки и как их избежать

Самая частая ошибка — «Таблица не найдена» при обращении к временной таблице из другого запроса. Причина почти всегда в том, что запросы используют разные менеджеры или менеджер не задан вовсе. Проверяйте, что свойство МенеджерВременныхТаблиц установлено у каждого запроса цепочки.

Вторая ошибка — обращение к таблице после УНИЧТОЖИТЬ. Платформа не подскажет это статически, ошибка возникнет только в момент выполнения. При рефакторинге пакетных запросов внимательно отслеживайте порядок шагов.

Типичные ошибки
01
Выполнение ПОМЕСТИТЬ и чтение таблицы разными запросами без общего менеджера — ошибка «Таблица не найдена»
02
Хранение менеджера в реквизите формы без очистки — рост потребления памяти на сервере
03
Повторное создание таблицы с тем же именем без УНИЧТОЖИТЬ — ошибка «Таблица уже существует»
04
Уничтожение таблицы до последнего использования — ошибка в середине пакета запросов
05
Создание менеджера внутри цикла вместо очистки таблиц между итерациями — лишняя нагрузка на СУБД

Как проверить поведение в конкретном коде

Для диагностики удобно использовать отладчик: поставьте точку останова после выполнения запроса и посмотрите свойства менеджера временных таблиц. Также можно выполнить пробный запрос ВЫБРАТЬ * ИЗ ВТ_Данные — если таблица жива, запрос выполнится, если уничтожена, получите ошибку.

В клиент-серверном режиме дополнительно полезен технологический журнал с событиями DBMSSQL/DBPOSTGRS: по ним видно, когда платформа физически создаёт и удаляет временные таблицы в СУБД.

Контрольные точки

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

Обращение к таблице из следующего запроса того же менеджера
Норма

Запрос выполняется, данные доступны

Тревожный признак

Ошибка «Таблица не найдена» — менеджеры различаются

Повторное создание таблицы с тем же именем
Норма

Перед созданием выполнен УНИЧТОЖИТЬ, ошибок нет

Тревожный признак

Ошибка «Таблица уже существует»

Память сеанса после выполнения обработки
Норма

Потребление возвращается к исходному уровню

Тревожный признак

Память растёт с каждым вызовом — таблицы не очищаются

Итог

Что важно запомнить

Временная таблица живёт ровно столько, сколько живёт её менеджер временных таблиц. Локальный менеджер — таблица исчезает при выходе из процедуры; менеджер в реквизите — до закрытия объекта. Для ручной очистки используйте команду УНИЧТОЖИТЬ, а все запросы цепочки связывайте одним менеджером.

Частые вопросы

Уничтожается ли временная таблица после выполнения запроса?

Если менеджер временных таблиц не задан явно — да, платформа создаёт временный менеджер и удаляет все таблицы по завершении пакета. Если менеджер задан и хранится в переменной — таблица живёт, пока жив менеджер.

Что будет, если создать таблицу с именем, которое уже существует?

Платформа выдаст ошибку «Таблица уже существует». Перед повторным созданием выполните УНИЧТОЖИТЬ с тем же именем или используйте уникальные имена.

Нужно ли уничтожать временные таблицы в файловой базе?

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

Видны ли временные таблицы другим пользователям или сеансам?

Нет. Временные таблицы существуют только в рамках своего менеджера и соединения с СУБД. Другой сеанс не может ни прочитать, ни случайно удалить их.

Можно ли передать временную таблицу между клиентом и сервером?

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

Чем УНИЧТОЖИТЬ отличается от удаления менеджера?

УНИЧТОЖИТЬ удаляет одну конкретную таблицу, остальные остаются доступными. Уничтожение менеджера (потеря всех ссылок на него) удаляет сразу все его таблицы. Используйте УНИЧТОЖИТЬ для точечной очистки внутри длинных алгоритмов.