Некоторая путаница в описании последовательности чтения в Oracle
Ниже приведен краткий обзор согласованности чтения из руководства по концепциям оракула.
Что такое оператор SQL, только один SQL? Или Pl/SQL или процедура хранения? Кто-нибудь может помочь предоставить мне один противоположный пример, который может указывать на непоследовательность прочитанного?
read consistency
A consistent view of data seen by a user. For example, in statement-level read
consistency the set of data seen by a SQL statement remains constant throughout
statement execution.
1 ответ
"Утверждение" в этом контексте - это одно утверждение DML: одно SELECT
, INSERT
, UPDATE
, DELETE
, MERGE
,
Это не блок PL/SQL. Аналогичным образом, несколько исполнений одного и того же оператора DML (скажем, в цикле PL/SQL) являются отдельными "операторами". Если вам нужна согласованность по нескольким операторам или внутри блока PL/SQL, вы можете добиться этого, используя SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
или же SET TRANSACTION READ ONLY
, Оба вводят ограничения.
Противоположный пример несогласованного чтения будет следующим.
Начальные условия: таблица BIG_TABLE
имеет 10 миллионов строк.
Пользователь А в 10:00:
SELECT COUNT(*) FROM BIG_TABLE;
Пользователь Б в 10:01:
DELETE FROM BIG_TABLE WHERE ID >= 9000000; -- delete the last million rows
Пользователь Б в 10:02:
COMMIT;
Пользователь А в 10:03: запрос завершен:
COUNT(*)
--------------
9309129
Это не правильно. Пользователь А должен был получить 10 миллионов строк или 9 миллионов строк. Ни в одной точке 9309129 зафиксированных строк в таблице не было. Произошло то, что пользователь A прочитал 309 129 строк, которые пользователь B удалял до того, как Oracle действительно обработал удаление (или до того, как COMMIT
). Затем, после удаления / подтверждения пользователем B, запрос пользователя A перестал видеть удаленные строки и прекратил их подсчет.
Проблема такого рода невозможна в Oracle благодаря реализации Multiversion Read Consistency.
В Oracle, в описанной выше ситуации, поскольку он столкнулся с блоками, у которых строки были удалены (и зафиксированы) пользователем B, запрос пользователя A использовал бы данные UNDO для восстановления того, как эти блоки выглядели в 10:00 - время, когда пользователь A запрос начался.
По сути, это так - операторы Oracle работают с версией базы данных, существовавшей на определенный момент времени. Этот момент времени почти всегда является временем начала заявления. Есть некоторые исключительные случаи, связанные с обновлениями, когда этот момент времени будет перемещен в момент времени "промежуточный оператор". Но это всегда последовательно в тот или иной момент времени.