Разработка успешных приложений для Oracle
полнена транзакция, переводящая 400 $ со счета 123 на счет 456? Наш запрос прочтет
500 $ в строке 4 и выдаст результат 1650 $, не так ли? Конечно, этого надо избежать,
так как подобный результат ошибочен — никогда такого баланса по счетам в базе дан-
ных не было. Нужно понять, как СУБД Oracle избегает подобных ситуаций и чем отли-
чаются используемые при этом методы от используемых во всех остальных СУБД.
Практически в любой другой СУБД для получения "согласованного" и "корректно-
го" ответа на этот запрос необходимо блокировать либо всю таблицу, по которой идет
суммирование, либо строки по мере их чтения. Это предотвратит изменение результата
другими сеансами в ходе его получения. Если заблокировать всю таблицу, будет полу-
чен результат, соответствующий состоянию базы данных в момент начала выполнения
запроса. Если блокировать данные по мере чтения (такая разделяемая блокировка чте-
ния предотвращает изменения, но не чтение данных другими сеансами), будет получен
результат, соответствующий состоянию базы данных в момент завершения выполнения
запроса. Оба эти метода существенно снижают возможности одновременного доступа.
Блокировка таблицы предотвращает любые изменения таблицы во время выполнения
запроса (для таблицы из четырех строк этот период очень короток, но для таблиц с сот-
нями тысяч строк запрос может выполняться несколько минут). Метод "блокирования
по ходу чтения" предотвращает изменение уже прочитанных и обработанных данных и
потенциально может приводить к взаимным блокировкам выполнения вашего запроса
и других изменений.
Как уже было сказано, вы не сможете в полном объеме использовать преимущества
СУБД Oracle, если не понимаете концепцию многовариантности. В СУБД Oracle мно-
говариантность используется для получения результатов, соответствующих моменту
начала выполнения запроса, при этом не блокируется ни единой строки (пока транзак-
ция по переводу денег изменяет строки 1 и 4, они будут заблокированы от других изме-
нений, но не от чтения, выполняемого, например, нашим запросом SELECT SUM...)-
Фактически в СУБД Oracle нет "разделяемых блокировок чтения", типичных для дру-
гих СУБД, — они в ней просто не нужны. Все устранимые препятствия для одновре-
менного доступа были устранены.
Итак, как же СУБД Oracle получает корректный, согласованный результат (1250 $)
при чтении, не блокируя данных, другими словами, не мешая одновременному досту-
пу? Секрет — в механизме выполнения транзакций, используемом в СУБД Oracle. При
любом изменении данных Oracle создает записи в двух разных местах. Одна запись по-
падает в журналы повторного выполнения, где Oracle хранит информацию, достаточ-
ную для повторного выполнения, или "наката", транзакции. Для оператора вставки это
будет вставляемая строка. Для оператора удаления это будет запрос на удаление строки
в слоте X блока Y файла Z. И так далее. Другая запись — это запись отмены, помещае-
мая в сегмент отката. Если транзакция завершается неудачно и должна быть отменена,
СУБД Oracle будет читать "предварительный" образ из сегмента отката, восстанавливая
необходимые данные. Помимо отмены транзакций, СУБД Oracle использует сегменты
отката для отмены изменений в блоках при их чтении, то есть для восстановления дан-
ных блока на момент начала выполнения запроса. Это позволяет читать данные несмотря
на блокировку и получать корректные, согласованные результаты, не блокируя данные.
Do'stlaringiz bilan baham: