Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СУБД Oracle / Лекции / Лек_ORAC / Lfg / Алгоритмы совместного доступа к базам данных.doc
Скачиваний:
59
Добавлен:
16.04.2013
Размер:
124.93 Кб
Скачать

Табличные блокировки

Когда транзакция блокирует строку, она автоматически устанавливает блокировку таблицы, содержащей заблокированную строку, чтобы предотвратить возникновение конфликтов между операциями DDLи операциями обновления строк таблицы.

Например, при обновлении строки таблицы CUSTOMERSтранзакция устанавливает исключающую блокировку обновляемой строки. Кроме того, устанавливается и блокировка таблицыCUSTOMERSтак, что другие транзакции не могут изменить или удалить эту таблицу до завершения первой транзакции.

Разделяемые или исключающие блокировки таблиц могут устанавливаться во время обработки транзакций. Транзакция всегда устанавливает разделяемую блокировку таблицы при выполнении таких базовых операций DML, какINSERT,UPDATEиDELETE. Транзакция устанавливает исключающую блокировку таблицы только в том случае, когда эта транзакция содержит операторLOCKTABLE(блокировать таблицу), явно требующий исключающей блокировки. Например, когда в транзакции содержится приведенный ниже операторLOCKTABLE, она устанавливает исключающую блокировку таблицыCUSTOMERS:

LOCK TABLE customers

In exclusive mode

NOWAIT;

Здесь, как и в приведенном выше примере, ключевое слово NOWAITтакже передает управление пользователю, еслиOracleне может немедленно установить запрашиваемую табличную блокировку; без ключевого словаNOWAITтранзакция будет находиться в режиме ожидания до тех пор, пока не сможет установить исключающую блокировку таблицыCUSTOMERS.

В Oracleсуществуют различные уровни табличных блокировок, не упомянутые здесь: строчный разделяемый, строчный исклю­чающий, разделяемый, разделяемый строчный исключающий и исключающий; каждый последующий тип табличной блокировки ограничивает более, чем предшествующий. Однако для простоты обсуждения были рассмотрены только основные различия между разделяемыми и исключающими блокировками, а также между блокировками на уровне строк и на табличном уровне.

Тупики

Тупик (deadlock) —это достаточно интересная ситуация, когда две транзакции не могут продолжать свою работу из-за того, что каждая из них запрашивает конфликтный набор блокировок. На рис. 2 показана ситуация, когда две транзакции взаимоблокированы.

На рис. 2 транзакция 1 устанавливает исключающую блокировку строки 1 таблицы и ждет, пока транзакция 2 снимет исключающую блокировку строки 2. Одновременно транзакция 2 устанавливает исключающую блокировку строки 2 и ждет, пока транзакция 1 снимет свою блокировку строки 1. В результате ни одна из этих транзакций не может продолжить работу, и они, оказавшись в тупике, ждут друг друга.

Транзакция 1

Имеет блокировку

Ожидает блокировки

Таблица

Строка #1

Строка #2

Транзакция 2

Ожидает блокировки

Имеет блокировку

Рис. 2. Две транзакции в тупике.

Тупики обычно возникают из-за неграмотно спроектированных транзакций. Для примера рассмотрим две такие транзакции, в каждой из которых содержится несколько операторов обновления данных таблицы PARTS. Каждая транзакция блокирует те строки, которые требуются другой транзакции, что приводит к тупику.

Транзакция 1

Транзакция 2

UPDATE sales.parts

SET onhand = onhand - 10

WHERE id =1;

UPDATE sales.parts

SET onhand = onhand - 10

WHERE id =2;

UPDATE sales.parts

SET onhand = onhand - 10

WHERE id = 2;

UPDATE sales.parts

SET onhand = onhand - 10

WHERE id = 1;

ждет, пока транзакция 2

снимет блокировку эл-та 2

ждет, пока транзакция 1

снимет блокировку эл-та 1

Недостаток обеих транзакций заключается в том, что в каждой из них содержится несколько несвязанных операторов обновления таблицы PARTS. Лучший вариант выполнения этих транзакций, устра­няющий опасность тупика, — каждый раз обновлять таблицыPARTSв отдельной транзакции:

Транзакция 1

Транзакция 2

UPDATE sales.parts

SET onhand = onhand - 10

WHERE id = 1;

UPDATE sales, parts

SET onhand = onhand - 10

WHERE id = 2;

COMMIT;

блокировка строки снята

COMMIT;

блокировка строки снята

UPDATE sales.parts

SET onhand = onhand - 10

WHERE id = 2;

UPDATE sales.parts

SET onhand = onhand - 10

WHERE id = 1;

COMMIT;

блокировка строки снята

COMMIT;

блокировка строки снята

При такой структуре транзакций строчные блокировки, устанавливаемые во время каждой операции обновления, вскоре снимаются, что помогает избежать тупика.

УСТРАНЕНИЕ ТУПИКОВ.Когда транзакция выполняет оператор, вызывающий тупик,Oracleавтоматически распознает тупик и откатывает такой оператор.