указанной фразой WHERE. П осле этого Т2 вставляет новую строку,
которая также удовлетворяет условию фразы WHERE запроса, который
ранее был использован Т1. Затем Т1 еще раз читает эти же строки,
используя тот же самый запрос, но теперь она видит дополнительную
строку, только что вставленную транзакцией Т2. Эту новую строку
принято называть "фантомной", поскольку для Т1 эта строка кажется
появившейся магическим образом.
■ Неповторяющиеся чтения. Транзакция Т1 читает строку, а затем Т2
обновляет строку, которую только что прочла Т1. После этого Т1
еще раз читает ту же самую строку и обнаруживает, что она изменилась
по сравнению с прошлым чтением. Такая ситуация называется
неповторяющимся чтением, поскольку строка, первоначально прочитанная
Т1, подверглась изменению.
■ Грязные чтения. Транзакция Т1 обновляет строку, но не фиксирует
сделанные изменения. Транзакция Т2 читает обновленную строку.
Затем Т1 выполняет откат, отказываясь от ранее сделанного изменения.
После этого строка, только что прочитанная Т2, перестает быть
допустимой (становится "грязной"), так как изменения, сделанные
Т1, не были зафиксированы, когда они читались транзакцией Т2.
Чтобы справиться с этими потенциальными проблемами, база данных
реализует разные уровни изоляции транзакций, не позволяющие различным
транзакциям взаимодействовать друг с другом. Стандарт SQL определяет
следующие уровни изоляции транзакций, показанные в порядке возрастания
изоляции.
■ READ UNCOMMITTED (Читать незафиксированное) Разрешены фантомные,
неповторяющиеся и грязные чтения.
280 Гпава 8
■ READ COMMITTED (Читать только зафиксированное) Разрешены фантомные
и неповторяющиеся чтения, а грязные чтения запрещены.
■ REPEATABLE READ (Повторяющиеся чтения) Разрешены фантомные чтения,
а неповторяющиеся чтения и грязные чтения запрещены.
■ SERIALIZABLE (Упорядочиваемый) Запрещены фантомные, неповторяющиеся
и грязные чтения.
База данных Oracle поддерживает уровни изоляции транзакций READ
COMMITTED и SERIALIZABLE. Уровни изоляции READ UNCOMMITTED и REPEATABLE
READ не поддерживаются.
Уровнем изоляции по умолчанию, определяемым стандартом SQL, является
SERIALIZABLE, но база данных Oracle по умолчанию поддерживает
уровень изоляции транзакций READ COMMITTED, который обычно оказывается
приемлемым практически для всех приложений.
Предупреждение Хотя при работе с базой данных Oracle можно использовать уровень изоляции
SERIALIZABLE, это может значительно увеличить время, необходимое для завершения
оператора SQL, поэтому следует использовать этот уровень только в случае крайней необходимости.
________
Для установки уровня изоляции транзакций используется оператор SET
TRANSACTION. К примеру, следующий оператор установит уровень изоляции
транзакций на SERIALIZABLE:
П SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
Ниже вы увидите пример транзакции, которая использует уровень изоляции
SERIALIZABLE.
Пример транзакции уровня SERIALIZABLE
В этом разделе вы увидите пример, который демонстрирует результат
установки уровня транзакций на SERIALIZABLE.
В этом примере используются две транзакции - Т1 и Т2. Транзакция Т1
имеет уровень изоляции по умолчанию READ COMMITTED, а транзакции Т2
назначен уровень SERIALIZABLE. Транзакции Т1 и Т2 читают строки из таблицы
customers, затем Т 1 вставляет одну новую строк)7 и обновляет одну
существующую строку в таблице customers. Поскольку Т2 имеет уровень
SERIALIZABLE, она «не видит» ни вставленной строки, ни внесенных в существующую
строку изменений даже после того, как Т 1 зафиксирует свои
изменения. Это связано с тем, что чтение вставленной строки было бы
фантомным чтением, а чтение обновленной строки — неповторяющимся
чтением, т. е. режимами, не разрешенными для транзакций уровня
SERIALIZABLE.
В таблице 8.2 показаны операторы SQL, из которых состоят транзакции
Т1 и Т2, в том чередующемся порядке, в котором эти операторы должны
быть выполнены.
Изменение содержимого таблиц 281
Таблица 8.2. Транзакции SERIALIZABLE
Транзакция 1 Т1 (READ COMMITTED)
(3) SELECT * FROM customers;
(4) INSERT INTO customers (customer,
id, first.name, last.name) VALUES (8.
'Steve', 'Button');
(5) UPDATE customers SET last.name =
'Yellow' WHERE customer_id = 3;
(6) COMMIT;
(7) SELECT *FR0M customers; Возвращаемый
результирующий набор содержит новую
строку и обновление.
Транзакция 2 Т2 (SERIALIZABLE)
(1) SET TRANSACTION ISOLATION LEVEL
SERIALIZABLE;
(2) SELECT * FROM customers;
(8) SELECT * FROM customers; Возвращаемый