Oracle для профессионалов



              

Многоверсионность - часть 3


select sum(account_balance) from accounts;

Конечно, в данном примере ответ очевиден - 1250 $. Однако что произойдет, если мы прочитаем строку 1, а при считывании строк 2 и 3 с одного из банкоматов будет выполнена транзакция, переводящая 400 $ со счета 123 на счет 456? Наш запрос прочтет 500 $ в строке 4 и выдаст результат 1650 $, не так ли? Конечно, этого надо избежать, так как подобный результат ошибочен — никогда такого баланса по счетам в базе данных не было. Нужно понять, как СУБД Oracle избегает подобных ситуаций и чем отличаются используемые при этом методы от используемых во всех остальных СУБД.

Практически в любой другой СУБД для получения "согласованного" и "корректного" ответа на этот запрос необходимо блокировать либо всю таблицу, по которой идет суммирование, либо строки по мере их чтения. Это предотвратит изменение результата другими сеансами в ходе его получения. Если заблокировать всю таблицу, будет получен результат, соответствующий состоянию базы данных в момент начала выполнения запроса. Если блокировать данные по мере чтения (такая разделяемая блокировка чтения предотвращает изменения, но не чтение данных другими сеансами), будет получен результат, соответствующий состоянию базы данных в момент завершения выполнения запроса. Оба эти метода существенно снижают возможности одновременного доступа. Блокировка таблицы предотвращает любые изменения таблицы во время выполнения запроса (для таблицы из четырех строк этот период очень короток, но для таблиц с сотнями тысяч строк запрос может выполняться несколько минут). Метод "блокирования по ходу чтения" предотвращает изменение уже прочитанных и обработанных данных и потенциально может приводить к взаимным блокировкам выполнения вашего запроса и других изменений.

Как уже было сказано, вы не сможете в полном объеме использовать преимущества СУБД Oracle, если не понимаете концепцию многоверсионности. В СУБД Oracle многоверсионность используется для получения результатов, соответствующих моменту начала выполнения запроса, при этом не блокируется ни единой строки (пока транзакция по переводу денег изменяет строки 1 и 4, они будут заблокированы от других изменений, но не от чтения, выполняемого, например, нашим запросом SELECT SUM...). Фактически в СУБД Oracle нет "разделяемых блокировок чтения", типичных для других СУБД, — они в ней просто не нужны. Все устранимые препятствия для одновременного доступа были устранены.




Содержание  Назад  Вперед