В данный момент уже очень многие конфигурация содержат БСП (библиотеку стандартных подсистем), в составе которой есть подсистема "Версионирование объектов". Эту подсистему можно использовать как в в режиме "Управляемого приложения", так и в принципе и в режиме "Обычного приложения" без появления автоматической команды для просмотра истории в форме объекта.
Что делает эта подсистема? Подсистема предназначена для хранения версий объектов (справочников, объектов), которые может многократно менять пользователь или обработки. В дальнейшем всегда можно посмотреть все версии, которые были изменены и сравнить их между собой. В результате вопрос кто виноват и когда это было сделан решен, это классно!!!
Включается эта подсистема в интерфейсу управляемого приложения в пункте "Администрирование-настройка системы - Использовать версионирование объектов". Далее настраивается виды объектов, т.к. какие документы и справочники, по которым будет идти версионирование.
Кстати говоря, о вариантах версионирования, то вариант "Версионировать при проведении" означает, что сохраняется версия документа после первого проведения, а затем уже всё время, чтобы с документом не делали версия сохраняется при записи. Поэтому правильнее было бы его назвать "Начать версионировать после первого проведения документа".
Но как уже упоминалось выше проблема в том, подсистема слишком напрягает базу, а именно возникают проблемы:
- Тратится время на сохранение версии объекта. Это влияет на то, что например перепроведение документов заметно замедляется .
- Заметно увеличивается размер базы данных, что требует беспокоится о свободном месте, где находится база данных. Да и раздражает немного, что выгрузка базы (dt) занимает гораздо больше времени.
Проанализируем эти проблемы и попробуем найти пути оптимизации.
1. Тратится время на сохранение версии объекта
- Механизм сохранения построен на подписке события для СправочникОбъект и ДокументОбъект событи ПриЗаписи. Последовательность такова:
- определяется нужно ли этот объект версионировать , определяется это из настроек в регистре сведений НастройкиВерсионированияОбъектов
- версия объект сериализуется в XML, помещается в ХранилищеЗначений и записывается в регистр сведений ВерсииОбъектов, при этом каждой версии присвается следующий порядковый номер в записи в реквизте НомерВерсии
Основное время уходит как на сериализацию объект (преобразования в XML) и собственно на запись этого серилизованной версии в регистр.
2. Заметно увеличивается размер базы данных
Размер увеличивается за счет количество сохраненных версий в регистре. Ведь каждая версия это по сути копия объекта и получается копий будет столько, сколько раз записывали документ (т.е. редактировали, проводили и отменяли проведения, помечали на удаление и т.п.). Так на один документ может приходиться и 10 версий и тогда у вас реально документов в базе "как бы" в 10 раз больше.
Решение этих проблем это смена подхода как к сохранению изменений, так и и количества сохраненных изменений. Есть много уже готовых решений, которые отлично работают(их много и на Infostart). Подходы у эти разработок сводится к тому, чтобы проанализировать , что именно изменилось и сохранить только изменения. А затем , когда есть текущая версия, то через динамику изменений можно восстановиться до любой версии. Некоторые решения ещё предлагают сохранять все эти изменения в другой специальной базе или время от время переносить накопленные изменения в другю специальную базу. Эти решения отлично работают, но ими нужно специально заниматься. Приобретать, устанавливать, настраивать. Но если требуется действительно серьезный и даже критический подход к хранению изменениям, то на это стоит потратить и время и деньги.
Но мы стараемся оптимизировать работы именно механизма работающего в БСП. Идея оптимизации будет состоять в том, чтобы уменьшить количество версий объектов, если реально эти объекты не меняются. Не будем сохранять версии объектов , если они не меняются, но будет фиксировать факт записи объекта в базу. Последнее нужно будет, например, чтобы знать документ перепроводили или нет.
Итак делаем
1.) Чтобы можно анализировать измененность объектов события ПриЗаписи не подходит, т.к. в этот момент уже предыдущая версия перезаписана. Поэтому будем использовать событие ПередЗаписью. Создадим две подписки на событие ПередЗаписью отдельно для справочника и документа для того, чтобы дополнительно зафиксировать информацию о режиме записи документа (проведение, отмена проведения, запись). Также дополнительно сохранять будет информацию о пометке удаления объекта, это позволит визуально быстро понимать, что с объектом ничего не делали, а просто пометили на удаление. Сами процедуры обработчики события поместим в общий модуль ВерсионированияСобытия. Таким образом, в обработчике события ПередЗаписью, когда объект ещё не записан в базу, текущая версия будет находится в Источнике (справочникОбъект или документОбъект), а предыдущая версия в Источник.Ссылка.
2.) Проверив, что объект версионируется, начинаем анализировать , а изменился ли объект? Как ? Тут я решли поступить просто раз объект сериализуется в XML,а XML это строка, а строки можно сравнивать. Берем XML текущего объекта и XML версии в базе данных и сравниваем, если ещё точнее сравнивать будет строки XML помещенные в ХранилищеДанных сжатые. Выглядет примерно это так:
3.) Если версию отличаются, то значит её нужно просто всю записать (не разницу чем отличается). Если не отличается, то саму версию сохранять не будет, однако запись о том, что объект записывался (проводился и т.п.) добавим в регистр сведений. При этом сделаем на ссылку на номер записи, от которой данная версия не отличается.
4.) Есть ещё один момент. Не будем сохранять текущую версия объекта сразу при записи, а только если появляется новая действительно измененная версия. А зачем сохранять текущую версию сразу, если она и так в базе сидит в виде документа. Это позволит, если документ один раз ввели и потом практически не меняли, то количество версий сохраненных будет минимально.
5.) Таким образом в регистре сведений ВерсииОбъектов будут записи , в которых действительно хранятся версии объекта (базовые версии), а остальные записи ссылаются только на базовые версии, т.к. при записи объектов они не менялись.
6.) Так как на сравнение версий все равно уходит время, нужно предусмотреть, чтобы в ситациях когда это не нужно делать, можно было обойтись без этой проверки. Например, делаем перепроведение документов , сами документы при этом не меняются, зачем что-то сравнивать. Поэтому добавим в ДополнительныеСвойства объекта флаг ПроверятьНаИзменениеСПредыдущимиВерсиями. Но чтобы этого флаг добавить придётся делать собственную обработку по групповому перепроведению документов, я их обычно делаю или беру где-нибудь для работы в программах, пользователи пользуются только этим перепроведением.
7.) Чтобы теперь сравнивать версии нужно учитывать, что в каждой записи сохраненной версии может и не быть, а также то, что текущие базовые версии не содержат в себе данные о версии ,т.к. эта версия сейчас и есть объект в базе . Поэтому нужно эти нюансы учесть в отчете о сравнении версий ОтчетПоИзменениямВерсийОбъектов
8.) Для анализа сколько и чего уже хранится в регистре сведений ВерсииОбъектов сделан новый отчет СтастикаПоХраненимымВерсиямОбъектов, в котором можно посмотреть данные о количестве объектов, версиях , базовых версиях, размерах храненимых версиях в мегабайтах (да это тоже сохраняется при записи версии в регистр)
В итоге изменений не так уж и много нужно внести 2-3 процедуры в общий модуль Версионирования, в модуль объекта отчета о сравнении, в регистр сведений добавить новые реквизиты. Результат будет существенное экономия места в базе и скорость перепроведения (своей обработкой) возрастет.
Все что получилось выкладываю в своей базе небольшой демо базе с одним документом и справочником, там же есть простая своя обработка перепроведения документов. Всё это можно использовать как доработку БСП , так и как отдельное решение сравнив и объединив. При встраивании в свои конфигурации нужно понмнить о том, что список объектов нужно задать в общей команде ИсторияИзменений в типе параметров команды, а также тип измерения Объект в регистре сведений ВерсииОбъектов, основная измененная процедура - это ВерсионированиеОбъект. ЗаписатьВерсиюОбъекта. В качестве основы бралась старая версия БСП 1.1.2.3, но текущая версия по этой подсистеме принципиально не отличается.