При работе с крупными базами данных, особенно после переноса информации из других систем (например, из УПП в современные конфигурации), специалисты часто сталкиваются с необходимостью массовой очистки справочников. Типичная ситуация: вы программно пометили тысячи неиспользуемых объектов на удаление, но при попытке окончательно очистить базу система выдает ошибку Ошибка разделенного доступа к базе данных или требует установить монопольный режим. В этой статье мы подробно разберем, почему это происходит, в чем разница между встроенными инструментами платформы и как выполнить удаление, не выгоняя пользователей из системы.
Когда мы запускаем процедуру «Удаление помеченных объектов» через меню «Все функции» (или «Функции для технического специалиста») — «Стандартные», мы обращаемся напрямую к сервисной функции платформы. В некоторых версиях 1С и при определенных настройках этот механизм пытается выполнить метод УстановитьМонопольныйРежим(True). Это делается для максимального ускорения процесса: система блокирует всю базу, чтобы гарантировать, что во время поиска и удаления ссылок ни один пользователь не создаст новый документ, ссылающийся на удаляемый объект.
Если в базе находится хотя бы один активный сеанс или выполняется регламентное задание, выполнение метода SetExclusiveMode прерывается с ошибкой. Проанализируем ситуацию: даже если вы видите, что в списке пользователей только вы, базу могут «держать» фоновые процессы, такие как:
Для корректной работы этого режима необходимо не только завершить сеансы пользователей, но и заблокировать регламентные задания в консоли администрирования кластера.
Важно понимать, что в современных конфигурациях на базе БСП (Библиотеки стандартных подсистем) существует два разных способа удаления. Рассмотрим их подробнее, чтобы понять, почему они ведут себя по-разному:
Почему одна обработка удаляет, а другая — нет? Проанализируем ситуацию, описанную в теме: в тестовой базе платформенный сервис удаляет объект, а программная обработка БСП пишет «есть ссылки». Это происходит из-за разной глубины проверки. Обработка БСП может учитывать ссылки в регистрах сведений (например, в регистрах соответствия при обмене данными), которые платформенный механизм в определенных режимах может игнорировать. Также обработка БСП может проверять наличие ссылок в объектах, к которым у текущего пользователя ограничены права (RLS), что создает дополнительные сложности.
Чтобы выполнить удаление без выгона пользователей, мы рекомендуем использовать именно программную обработку. Рассмотрим алгоритм действий:
ИсторияДанных или СоответствияОбъектовИнформационныхБаз.Если вы уверены, что ссылки в этих регистрах не важны, их можно очистить программно или с помощью обработки «Групповое изменение реквизитов», после чего объект будет удален штатно.
Если вы абсолютно уверены, что на ваши объекты (например, старые договоры без оборотов) нет важных ссылок, и вы хотите избежать долгой проверки, можно воспользоваться методом непосредственного удаления. Посмотрим, как это реализовать в коде вашей собственной обработки:
// Пример программного удаления массива объектов
Процедура УдалитьОбъектыБезПроверки(МассивСсылок)
Для Каждого Ссылка Из МассивСсылок Цикл
Попытка
// Получаем объект из ссылки
ОбъектДляУдаления = Ссылка.ПолучитьОбъект();
Если ОбъектДляУдаления <> Неопределено Тогда
// Параметр Истина означает удаление без проверки ссылок
ОбъектДляУдаления.Удалить();
Сообщить("Объект удален: " + Ссылка);
КонецЕсли;
Исключение
Сообщить("Не удалось удалить: " + Ссылка + " Ошибка: " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
КонецПроцедуры
Важное предупреждение: Метод Объект.Удалить() уничтожает запись в базе данных мгновенно. Если на этот объект все же были ссылки в документах, на их месте появится надпись "<Объект не найден>...". Используйте этот метод только после тщательной проверки в тестовой базе!
В платформе 8.3 есть мощный метод УдалитьОбъекты(), который позволяет совместить контроль целостности и программное управление процессом. Рассмотрим пример его использования:
// Массив объектов, которые мы хотим удалить
МассивНаУдаление = Новый Массив;
МассивНаУдаление.Добавить(СсылкаНаДоговор);
// Таблица, куда вернутся найденные ссылки, если удаление невозможно
ТаблицаСсылок = Новый ТаблицаЗначений;
// Второй параметр Ложь - запрет непосредственного удаления при наличии ссылок
// Третий параметр - таблица найденных ссылок
УдалитьОбъекты(МассивНаУдаление, Ложь, ТаблицаСсылок);
Если ТаблицаСсылок.Количество() > 0 Тогда
Для Каждого Строка Из ТаблицаСсылок Цикл
Сообщить("Удалению мешает ссылка в: " + Строка.Данные);
КонецЦикла;
Иначе
Сообщить("Удаление выполнено успешно в разделенном режиме.");
КонецЕсли;
Этот метод работает эффективно и предоставляет полную информацию о том, какие именно записи в базе блокируют удаление. Проанализировав ТаблицаСсылок, вы сможете точечно очистить мешающие записи в регистрах. Для автоматизации очистки можно использовать инструмент для построения дерева связей и массового удаления зависимостей.
На основе разбора ситуации, выясним оптимальный порядок действий при очистке базы после переноса из УПП:
BackgroundJob.Таким образом, мы выяснили, что ошибка монопольного доступа — это особенность платформенного сервиса. Переход к программной обработке БСП или использование встроенных методов языка 1С (УдалитьОбъекты) позволяет решить задачу очистки базы в рабочем режиме, сохраняя при этом контроль над целостностью данных. При необходимости можно воспользоваться готовой внешней обработкой для фонового удаления объектов через БСП.