Russian Qt Forum

Qt => Базы данных => Тема начата: Akon от Декабрь 08, 2012, 11:45



Название: Undo/Redo базы данных
Отправлено: Akon от Декабрь 08, 2012, 11:45
Друзья, задача примерно такая: есть БД (на PostgreSQL), доступ пользователей на запись сериализован (ну, как мьютекс). Далее необходимо вести журнал изменений записей (изменение - это не транзакция, а атомарное изменение типа добавить/удалить запись или изменить значение столбца), доступный всем пользователям. Журнал единый, но с каждым изменением сопоставлен сделавший это изменение пользователь. Получивший доступ на запись пользователь имеет возможность выполнять Undo/Redo операции, в т.ч. изменения, сделанные другими пользователями. Структура таблиц постоянна, новые таблицы не создаются. Для связи приложения с БД используется ORM (OBD), т.е. функции СУБД редуцированы до простого хранилища, там нет бизнес-логики. В рамках данной задачи, по-возможности, хотелось бы придерживаться этого направления.

Тем не менее, имеются ли PostgreSQL встроенные средства для решения этой задачи, или нужно делать все самому (создавать дополнительные таблицы под журнал, следить за его соглавованностью и т.п.)?

Если у кого есть опыт решения подобной задачи, пожалуйста, поделитесь. Особенно, если было с ORM.



Название: Re: Undo/Redo базы данных
Отправлено: joker от Декабрь 27, 2012, 17:46
Сорри что времени много прошло - но лучше же поздно, чем никогда?

В общем случае такое для СУБД делается только руками, потому что нужно идти на множество компромиссов и допущений.

Пример:
Пользователь 1 создал запись ну пусть карточки клиента, а второй - выписал документ на этого клиента.
И как тут можно отменить действие первого?


В SQL примерно так работает механизм транзакций (он у тебя в БД априори), но:
1. Транзакция может подтверждаться только тем клиентом, который ее открыл. И только в той же сессии.
2. На объекты в неподтвержденной транзакции не может быть ссылок из других транзакций.
3. ORM работает на более высоком уровне. Его придется обходить.

Соотвествнно, в твоём случае, я бы делал так:
1. На каждую таблицу создавал бы таблицу логов (скриптами, ессно), все действия с осн. таблицей логгировать тригерами (которые тоже создаются скриптом, чтобы в случае изменения полей / и т.п. просто и быстро пересоздать все)
В логе для update / delete хранил бы старые элементы записей. Для insert-а вобщем не важно :).
2. Пользователю с правами давал бы на просмотр эти таблицы с выбором, до какого элемента откатывать.
3. Ну и раздел с удалениями не забыть :)