Выбрать главу

указанной фразой 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; Возвращаемый