Пример установил бы право контекста, пример ниже получает различные состояния объекта, который должен вернуться (откатываемый).
Состояние 1 - зарегистрированный 01 марта 2010
Column1 Column2
Data1 0.56
Состояние 2 - зарегистрированный 02 марта 2010
Column1 Column2
Data1 0.57
Состояние 3 - зарегистрированный 03 марта 2010
Column1 Column2
Data1 0.58
Пользователь замечает, что state3 не то, в чем он намеревался быть, решает вернуться назад к state2.
Один подход, о котором я могу думать, не изменяя объект, через "аудит" всего вставления/обновления, поскольку ниже, информация об откате собирает данные непосредственно перед обновлениями/модификациями на объекте, так, чтобы это могло быть применено в порядке, когда необходимо вернуться. Обратите внимание на то, что изменяя схему объекта, не опция.
Откат - R1, зарегистрированный 01 марта 2010
Column1 Column2
Data1 0.56
Откат - R2, зарегистрированный 02 марта 2010
Column1 Column2
Data1 0.56
Откат - R3, зарегистрированный 03 марта 2010
Column1 Column2
Data1 0.57
Так, для получения до state2 мы запустили бы с информации об откате R1, применили бы R2 на него.
Существует ли лучший подход для достижения этого?
Спасибо за внимание.
Для каждой таблицы в вашей схеме создайте новую таблицу аудита в другой схеме с двумя дополнительными столбцами: validFrom
и validTo
.
Когда вы вставляете / обновляете строку, вам нужно сделать два изменения в таблице аудита:
update auditTable set validTo = sysdate where validTo is null
insert auditTable ...copy-of-all-columns..., validFrom = sysdate
(без вставки, если вы удаляете строку в исходной таблице).
Если вам нужно вернуться в определенное состояние, вы можете выбрать строку в таблице аудита с тем же первичным ключом (PK), которая находится в диапазоне времени [validFrom, validTo)
или где validTo равно none
, и просто скопируйте строку в исходную таблицу.
Затем вы должны удалить все строки в исходной таблице, которые не существуют в то время в таблице аудита.
Просто обновите текущее значение / состояние до желаемого значения / состояния.
То есть, в общем, единственный вариант, который у вас есть. Причина этого в том, что вы не можете в целом предсказать влияние, которое ваш вид «отката» может иметь на целостность базы данных.
Ваш объект E1, имеющий состояние S3, мог быть предпосылкой для того, чтобы какой-либо другой объект E2 мог иметь некоторое состояние Sx, которое может быть «несовместимым» с E1, имеющим состояние S1.
Если разрешить E1 вернуться в его прежнее состояние S1, ничего не делая с E2, база данных станет несогласованной.
Вам нужен такой механизм, как FS ext3 в Linux - журналы. (Я не уверен, но это может быть модель ZFS для файловой системы Solaris, но это не важно)
Их идея состоит в том, чтобы хранить журнал для каждого файла (понимать его объект / запись / ...), и каждое изменение, которое происходит с ним, создает другую точку входа, хранящую только changes, таким образом, у вас нет репликации. У вас есть простой и быстрый откат - вы просто говорите, что хотите откатиться к 6 версиям назад, и файловая система делает следующее:
удаляет последние 6 версий и помечает currentVersion-6
как самую последнюю, и вы готовы к использованию.
Самое сложное - заставить магазин очков рассчитывать быстро и оптимизировать - я не знаю хороших алгоритмов расчета для новой записи в вашем журнале, но они должны быть в интернете.
Вы можете сделать что-то подобное адаптированным для БД. Как вы его находите? Я видел это в действии на Solaris с ZFS, и он работает очень быстро, и эта файловая система была награждена в прошлом году (или это был 2008 ...?) за очень высокое качество.
Это может не подходить для приложения, управляемого базой данных, но общий шаблон проектирования, который может помочь, - это Memento шаблон:
Вместо «применения» обновлений у вас может быть поле или отдельная справочная таблица, которая будет указывать «текущее» состояние объекта. Таким образом, откат будет заключаться в перемещении флага или изменении ссылки на другой объект в таблице аудита.