gifts2017

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

Опубликовал Владимир Рютин (VovkaPutin) в раздел Администрирование - Чистка базы

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

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

Процедура МеханизмВерсионированияОбъектов_ПриЗаписиОбъекта(Источник, Отказ) Экспорт
	
	Перем ЧислоВерсийОбъекта;
	
	Если ОбъектВерсионируется(Источник, ЧислоВерсийОбъекта) Тогда
		
		ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
		
		ЗаписьXML = Новый ЗаписьXML;
		ЗаписьXML.ОткрытьФайл(ИмяВременногоФайла); 
		ЗаписьXML.ЗаписатьОбъявлениеXML();
		ЗаписатьXML(ЗаписьXML, Источник, НазначениеТипаXML.Явное);
		ЗаписьXML.Закрыть();
		
		ДвоичныеДанные = Новый ДвоичныеДанные(ИмяВременногоФайла);
		//ХранилищеДанных = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9));       
		
		УдалитьФайлы(ИмяВременногоФайла);
		
		//ВерсионированиеОбъектовПривилегированный.ЗаписатьВерсиюОбъекта(Источник.Ссылка, ЧислоВерсийОбъекта, ХранилищеДанных);  

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

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

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

Скачать файлы

Наименование Файл Версия Размер
Удаление одинаковых версий 23
.epf 8,59Kb
10.08.15
23
.epf 8,59Kb Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Maxim Goncharov (maxx) 10.08.15 13:53
В текущей версии БСП одинаковые версии на записываются при перепроведении/перезаписи.
u_n_k_n_o_w_n; +1 Ответить 1
2. Владимир Рютин (VovkaPutin) 10.08.15 13:58
(1) maxx, не все сидят на текущей версии :)
3. Иван Петров (dgolovanov) 10.08.15 15:14
Решал эту же проблему недавно. Сделал иначе:
http://infostart.ru/public/96713/, комментарий 23 - листинг кода получения хэша из строки.
В регистр добавил еще одно измерение и сравниваю не объекты, а хэши - работает быстрее. А в 8.3 поддержка хэширования реализована на уровне платформы. Ну да это я пишу чисто поделиться информацией.
4. Владимир Зленко (ZLENKO) 10.08.15 17:52
На эту тему еще есть обработка сжатия версий http://infostart.ru/public/321131/
5. Дмитрий Бухалов (Re:аниматор) 18.08.15 07:27
В ряде случаев выходит ошибка

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

по причине:
Ошибка преобразования
по причине:
bad allocation


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


Данное решение не работает с большими документами. В моем случае документ содержит 68 287 строк
VovkaPutin; +1 Ответить
6. Дмитрий Бухалов (Re:аниматор) 18.08.15 09:27
Сделал, всё работает


			//Если ЗначениеВСтрокуВнутр(ПредыдущаяВерсияОбъекта) <> ЗначениеВСтрокуВнутр(ДвоичныеДанные) Тогда //Сравниваем версии
			Если КонтрольнаяСумма(СериализоватьОбъект(ДвоичныеДанные)) <> КонтрольнаяСумма(СериализоватьОбъект(ПредыдущаяВерсияОбъекта)) Тогда

...

// Возвращает сериализованный объект в виде двоичных данных.
//
// Параметры:
//  Объект - Любой - сериализуемый объект.
//
// Возвращаемое значение:
//  ДвоичныеДанные - сериализованный объект.
Функция СериализоватьОбъект(Объект) Экспорт
	
	ЗаписьXML = Новый ЗаписьFastInfoset;
	ЗаписьXML.УстановитьДвоичныеДанные();
	ЗаписьXML.ЗаписатьОбъявлениеXML();
	
	ЗаписатьXML(ЗаписьXML, Объект, НазначениеТипаXML.Явное);
	
	Возврат ЗаписьXML.Закрыть();

КонецФункции

// Контрольная сумма по алгоритму MD5.
Функция КонтрольнаяСумма(Данные) Экспорт
	
	ХешированиеДанных = Новый ХешированиеДанных(ХешФункция.MD5);
	ХешированиеДанных.Добавить(Данные);
	Возврат СтрЗаменить(ХешированиеДанных.ХешСумма, " ", "");
	
КонецФункции



...Показать Скрыть


Работает и с большими объемами
VovkaPutin; +1 Ответить
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа