В том же (или в другом) сеансе мы затем удаляем все данные из таблицы. Более того, мы даже фиксируем (COMMIT) это удаление. Строк больше нет — не так ли? На самом деле их можно извлечь с помощью курсора. Фактически, результирующее множество, возвращаемое командой OPEN, было предопределено в момент открытия курсора. Мы не прочитали при открытии курсора ни одного блока данных таблицы, но результат оказался жестко зафиксированным. Мы не сможем узнать этот результат, пока не извлечем данные, но с точки зрения нашего курсора результат этот неизменен. Дело не в том, что СУБД Oracle скопировала все эти данные в другое место при открытии курсора; данные сохранил оператор delete, поместив их в область данных под названием сегмент отката.
Именно в этом и состоит согласованность по чтению, и если не понимать, как работает схема многоверсионности в Oracle и каковы ее последствия, вы не только не сможете воспользоваться всеми преимуществами СУБД Oracle, но и не создадите корректных приложений для Oracle, гарантирующих целостность данных.
Давайте рассмотрим последствия использования многоверсионной согласованности запросов по чтению и неблокируемых чтений. Для тех, кто не знаком с многоверсионностью, представленные ниже результаты могут показаться удивительными. Для простоты предположим, что в каждом блоке данных (это минимальная единица хранения в СУБД) считываемой таблицы хранится всего одна строка и что выполняется полный просмотр таблицы.
В запрашиваемой таблице хранятся балансы банковских счетов. Она имеет очень простую структуру:
create table accounts ( account_number number primary key, account_balance number );
В реальной таблице счетов будут сотни тысяч строк, но для простоты мы будем рассматривать таблицу всего с четырьмя строками (более детально мы рассмотрим этот пример в главе 3):
Строка | Номер счета | Баланс счета |
1 | 123 | 500,00 $ |
2 | 234 | 250,00 $ |
3 | 345 | 400,00 $ |
4 | 456 | 100,00 $ |
Требуется создать отчет, который в конце банковского дня позволяет определить количество денег в банке. Это делается с помощью предельно простого запроса: