Как программно удалить присоединенный файл в 1С и избежать конфликтов блокировок

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

При работе с современными конфигурациями 1С, такими как Управление торговлей 11, ERP 2 или Комплексная автоматизация, часто возникает задача программной очистки присоединенных файлов. Это могут быть изображения товаров, скан-копии документов или дополнительные файлы, которые со временем теряют актуальность и переполняют базу данных. Рассмотрим подробно, как правильно реализовать процедуру удаления, с какими трудностями можно столкнуться и как их преодолеть. В качестве альтернативы полному удалению для экономии места в базе можно использовать инструмент для автоматического сжатия изображений.

Анализируем проблему: ошибка "Конфликт блокировок"

Часто программисты пытаются использовать стандартный метод Удалить() для объекта справочника присоединенных файлов. Рассмотрим типичную ситуацию: у нас есть запрос, который выбирает все файлы, относящиеся к конкретной номенклатуре, и в цикле мы пытаемся их удалить. Однако система выдает ошибку: "Конфликт блокировок при выполнении транзакции: Превышено максимальное время ожидания предоставления блокировки".

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

  1. Открытая форма этого файла или карточка номенклатуры-владельца у одного из пользователей.
  2. Активный процесс фонового обмена (например, обмен с сайтом), который в данный момент считывает изображение.
  3. Подписки на события, которые при попытке удаления файла начинают выполнять дополнительные проверки или запись в связанные регистры, вызывая каскадную блокировку.

Вариант 1: Удаление через запрос и получение объекта

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    НоменклатураПрисоединенныеФайлы.Ссылка КАК Ссылка
    |ИЗ
    |    Справочник.НоменклатураПрисоединенныеФайлы КАК НоменклатураПрисоединенныеФайлы
    |ГДЕ
    |    НоменклатураПрисоединенныеФайлы.ВладелецФайла = &Номенклатура";

Запрос.УстановитьПараметр("Номенклатура", СсылкаНаНоменклатуру);

РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл
    // Получаем объект для удаления
    ОбъектФайла = Выборка.Ссылка.ПолучитьОбъект();
    Попытка
        ОбъектФайла.Удалить();
    Исключение
        Сообщить("Не удалось удалить файл: " + ОписаниеОшибки());
    КонецПопытки;
КонецЦикла;

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

Вариант 2: Использование прямой выборки из справочника

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


ВыборкаФайлов = Справочники.НоменклатураПрисоединенныеФайлы.Выбрать();

Пока ВыборкаФайлов.Следующий() Цикл
    Если ВыборкаФайлов.ВладелецФайла = НужнаяНоменклатура Тогда
        ОбъектФайла = ВыборкаФайлов.ПолучитьОбъект();
        // Перед удалением проверяем, не помечен ли файл на удаление уже
        Если Не ОбъектФайла.ПометкаУдаления Тогда
             ОбъектФайла.Удалить();
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

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

Правильный подход: использование программного интерфейса БСП

В современных конфигурациях 1С прямое физическое удаление через Удалить() не рекомендуется. В типовых решениях используется БСП (Библиотека стандартных подсистем), которая предоставляет специальные инструменты для работы с файлами. Выясним причину: присоединенный файл — это не просто запись в справочнике НоменклатураПрисоединенныеФайлы. Данные могут храниться:

Если мы просто удалим элемент справочника-владельца, физические данные могут остаться "мусором" в базе или на диске. Рассмотрим, как это сделать правильно через общий модуль БСП:


// Вместо физического удаления лучше установить пометку удаления
// Это позволит системе корректно очистить связанные данные позже
ПрисоединенныйФайлОбъект = СсылкаНаФайл.ПолучитьОбъект();
ПрисоединенныйФайлОбъект.УстановитьПометкуУдаления(Истина);

// Или использование специализированного метода БСП (если доступен в версии)
// ПрисоединенныеФайлы.УдалитьФайлыВладельца(Номенклатура);

Использование метода УстановитьПометкуУдаления(Истина) инициирует стандартные механизмы проверки ссылочной целостности. Затем регламентное задание "Очистка ненужных файлов" автоматически и безопасно удалит данные из базы и с дисковых томов.

Что делать, если блокировка сохраняется?

Если вы уверены, что код написан верно, но ошибка блокировки продолжает возникать, проанализируем следующие моменты:

  1. Кэш сервера 1С: Иногда информация о блокировках "зависает" в кластере. В тестовых целях можно попробовать очистить кэш или перезагрузить службу 1С.
  2. Фоновые задания: Проверьте консоль администрирования. Возможно, в данный момент выполняется индексация полнотекстового поиска или обмен данными, который накладывает монопольную блокировку на таблицы файлов.
  3. Транзакционность: Если ваш код удаления выполняется внутри другой большой транзакции (например, при проведении документа), блокировка будет удерживаться до самого конца основной операции. Попробуйте вынести удаление файлов из транзакции.

Итоги и рекомендации

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

Соблюдение этих структурных подходов позволит вам создавать надежные и быстрые инструменты для администрирования баз данных на платформе 1С:Предприятие 8.3.

← На главную