Сохранение результатов поиска согласованными для нескольких транзакций - PullRequest
6 голосов
/ 01 мая 2011

Мне необходимо реализовать требование для приложения Java CRUD, в котором пользователи хотят сохранить свои результаты поиска без изменений, даже если они выполняют действия, которые влияют на критерии, по которым возвращаемые строки сопоставляются.

Confused? Хорошо. Позвольте мне привести вам знакомый пример. В Gmail, если вы выполняете расширенный поиск по непрочитанным электронным письмам, вам предоставляется список подходящих результатов. Нажмите на запись и затем вернитесь к списку поиска. В результате вы только что прочитали эту запись, но она не исчезла из исходного набора результатов. Только эта строка изменилась с жирного на обычный.

Мне нужно реализовать точно такое же поведение, но приложение спроектировано таким образом, что сначала выполняется любая транзакция, а затем пользовательский интерфейс запрашивает базу данных для синхронизации. Сложность приложения и размер базы данных не позволяют мне просто выполнять кеширование в памяти соответствующих строк и вносить изменения как в БД, так и в памяти.

Я думаю о решении проблемы на уровне базы данных путем создания промежуточной таблицы в базе данных Oracle, содержащей указатели на соответствующие записи и запрашивающей только эти записи, чтобы синхронизировать пользовательский интерфейс с данными. Есть идеи?

Ответы [ 4 ]

4 голосов
/ 01 мая 2011

В Oracle, если вы открываете курсор, результаты этого курсора являются статическими, независимо от того, вставляет ли другая строка, которая появится в вашем курсоре, или обновляет или удаляет строку, которая существует в вашем курсоре.

Задача состоит в том, чтобы не закрывать курсор, если вы хотите, чтобы результаты были согласованы с моментом открытия курсора.

3 голосов
/ 02 мая 2011

Если пользовательский интерфейс поддерживает один сеанс в базе данных, одним из решений является использование глобальных временных таблиц в Oracle. Когда вы выполняете поиск, вставляете уникальные идентификаторы в GTT, тогда пользовательский интерфейс просто запрашивает GTT.

Если пользовательский интерфейс не поддерживает открытый сеанс, вы можете сделать то же самое, но с обычной таблицей. Тогда, конечно, вам просто нужно добавить код очистки, чтобы удалить старые результаты поиска из таблицы.

2 голосов
/ 01 мая 2011

Создать два подключения к базе данных.

Установите для первого из них значение ТОЛЬКО ДЛЯ ЧТЕНИЯ (используя SET TRANSACTION READ ONLY) при поиске по этому соединению, но убедитесь, что вы никогда не завершите эту транзакцию, выдав коммит или откат.

Поскольку транзакция только для чтения видит только те данные, которые были в момент ее запуска, первое соединение никогда не увидит никаких изменений в базе данных - даже зафиксированных.

Затем вы можете выполнять обновления во втором соединении, не влияя на результаты первого соединения.

Если вы не можете использовать два соединения, вы можете реализовать обновления с помощью хранимых процедур, использующих автономные транзакции, тогда вы можете оставить транзакцию только для чтения открытой в одном вашем подключении.

2 голосов
/ 01 мая 2011

Вы можете использовать ретроспективный запрос для чтения данных из прошлого. Например, select * from employee as of timestamp to_timestap('01-MAY-2011 070000', 'DD-MON-YYYY HH24MISS');

Oracle хранит эту историческую информацию только в течение ограниченного периода времени. Вам нужно будет просмотреть свои настройки хранения; параметр UNDO_RETENTION, гарантия сохранения правильного размера табличного пространства UNDO, а также большие объекты имеют свои собственные настройки хранения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...