Версионирование объектов — отключение создания одинаковых версий + обработка по их удалению

Стандартная процедура версионирования объектов создает одинаковые версии при перепроведении / перезаписи объекта без изменения реквизитов. Следовательно, база пухнет от пустых версий, особенно при закрытии месяца (проведение документов).

Но можно избавиться от создания клонов, реализация ниже (в Общем модуле ВерсионированиеОбъектов):

Процедура МеханизмВерсионированияОбъектов_ПриЗаписиОбъекта(Источник, Отказ) Экспорт

Перем ЧислоВерсийОбъекта;

Если ОбъектВерсионируется(Источник, ЧислоВерсийОбъекта) Тогда

ИмяВременногоФайла = ПолучитьИмяВременногоФайла();

ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ИмяВременногоФайла);
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписатьXML(ЗаписьXML, Источник, НазначениеТипаXML.Явное);
ЗаписьXML.Закрыть();

ДвоичныеДанные = Новый ДвоичныеДанные(ИмяВременногоФайла);
//ХранилищеДанных = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9));

УдалитьФайлы(ИмяВременногоФайла);

//ВерсионированиеОбъектовПривилегированный.ЗаписатьВерсиюОбъекта(Источник.Ссылка, ЧислоВерсийОбъекта, ХранилищеДанных);

// ++Владимир //вв // 06.08.2025 10:09:37
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
|    ВерсииОбъектов.ВерсияОбъекта
|ИЗ
|    РегистрСведений.ВерсииОбъектов КАК ВерсииОбъектов
|ГДЕ
|    ВерсииОбъектов.Объект = &Ссылка
|    И ВерсииОбъектов.НомерВерсии = &НомерВерсии";
Запрос.УстановитьПараметр("Ссылка", Источник.Ссылка);
Запрос.УстановитьПараметр("НомерВерсии", ЧислоВерсийОбъекта);
Выборка = Запрос.Выполнить().Выбрать();
Выборка.Следующий();

ПредыдущаяВерсияОбъекта = ?(Выборка.ВерсияОбъекта = Неопределено, Неопределено, Выборка.ВерсияОбъекта.Получить());

Если ЗначениеВСтрокуВнутр(ПредыдущаяВерсияОбъекта) <> ЗначениеВСтрокуВнутр(ДвоичныеДанные) Тогда //Сравниваем версии
ХранилищеДанных = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9));
ВерсионированиеОбъектовПривилегированный.ЗаписатьВерсиюОбъекта(Источник.Ссылка, ЧислоВерсийОбъекта, ХранилищеДанных);
КонецЕсли;
// --Владимир // 06.08.2025 10:09:37

КонецЕсли;

КонецПроцедуры

В комментарии (6) предложен альтернативный способ проверки версий (для «тяжелых» документов).

Также предлагаю Вам обработку по удалению уже созданных клонов. В форме необходимо внести ограничение по количеству версий (для отбора), нажать кнопку «Удалить» (только дубли). Удаление 155 467 одинаковых версий заняло чуть более часа (база похудела на 1,5 GB).

7 Comments

  1. maxx

    В текущей версии БСП одинаковые версии на записываются при перепроведении/перезаписи.

    Reply
  2. VovkaPutin

    (1) maxx, не все сидят на текущей версии 🙂

    Reply
  3. dgolovanov

    Решал эту же проблему недавно. Сделал иначе:

    http://infostart.ru/public/96713/, комментарий 23 — листинг кода получения хэша из строки.

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

    Reply
  4. ZLENKO

    На эту тему еще есть обработка сжатия версий http://infostart.ru/public/321131/

    Reply
  5. Re:аниматор

    В ряде случаев выходит ошибка

    Ошибка при выполнении обработчика — ‘ПриЗаписи’

    по причине:

    {ОбщийМодуль.ВерсионированиеОбъектов.Модуль(36)}: Ошибка при вызове метода контекста (ЗначениеВСтрокуВнутр)

    по причине:

    Ошибка преобразования

    по причине:

    bad allocation

    Погуглив, нашел

    Как правило, «bad allocation» происходит, когда производится попытка получить внутренее представление объекта с типом ХранилищеЗначения большого размера (большая картинка, таблица, документ и т.д.)..

    Данное решение не работает с большими документами. В моем случае документ содержит 68 287 строк

    Reply
  6. Re:аниматор

    Сделал, всё работает

    
    //Если ЗначениеВСтрокуВнутр(ПредыдущаяВерсияОбъекта) <> ЗначениеВСтрокуВнутр(ДвоичныеДанные) Тогда //Сравниваем версии
    Если КонтрольнаяСумма(СериализоватьОбъект(ДвоичныеДанные)) <> КонтрольнаяСумма(СериализоватьОбъект(ПредыдущаяВерсияОбъекта)) Тогда
    
    …
    
    // Возвращает сериализованный объект в виде двоичных данных.
    //
    // Параметры:
    //  Объект — Любой — сериализуемый объект.
    //
    // Возвращаемое значение:
    //  ДвоичныеДанные — сериализованный объект.
    Функция СериализоватьОбъект(Объект) Экспорт
    
    ЗаписьXML = Новый ЗаписьFastInfoset;
    ЗаписьXML.УстановитьДвоичныеДанные();
    ЗаписьXML.ЗаписатьОбъявлениеXML();
    
    ЗаписатьXML(ЗаписьXML, Объект, НазначениеТипаXML.Явное);
    
    Возврат ЗаписьXML.Закрыть();
    
    КонецФункции
    
    // Контрольная сумма по алгоритму MD5.
    Функция КонтрольнаяСумма(Данные) Экспорт
    
    ХешированиеДанных = Новый ХешированиеДанных(ХешФункция.MD5);
    ХешированиеДанных.Добавить(Данные);
    Возврат СтрЗаменить(ХешированиеДанных.ХешСумма, » «, «»);
    
    КонецФункции
    
    
    
    

    Показать

    Работает и с большими объемами

    Reply
  7. PASAHAKA
    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *