КАК СИСТЕМА DBРЕШАЕТ ЭТИ ТРИ ПРОБЛЕМЫ ПАРАЛЛЕЛЬНЫХ ПРОЦЕССОВ
Как уже упоминалось в начале предыдущего раздела, механизм управления параллельными процессами системы DB2, подобно предназначенным для этого механизмам большинства других доступных в настоящее время систем, основан на технике, называемой блокированием.
Главная идея блокирования проста: если транзакции нужны гарантии, что некоторый объект, в котором она заинтересована—обычно запись базы данных, не будет изменен каким-либо непредсказуемым образом в течение требуемого промежутка времени, она устанавливает блокировку этого объекта. Результат блокировки заключается в том, чтобы изолировать этот объект от других транзакций и, в частности, предотвратить его изменение средствами этих транзакций. Для первой транзакции, таким образом, имеется возможность выполнять предусмотренную в ней обработку, располагая определенными знаниями о том, что объект в запросе будет оставаться в стабильном состоянии до тех пор, пока данная транзакция этого пожелает.
Перейдем теперь к более детальному рассмотрению принципа действия блокирования конкретно для системы DB2. Начнем с некоторых упрощающих предположений.
1. Предполагается, что единственным видом объектов, подверженных действию механизма блокирования, является запись базы данных, т. е. строка базовой таблицы. Вопрос о блокировании объектов других видов отложим до раздела 11.6.
2. Будут обсуждаться только два вида блокировок, а именно — монопольные блокировки (тип X) и совместные блокировки (тип S) (Названия типов блокировок Х и S происходят от английских слов Shared (совместный) и exclusive (монопольный).—Примеч. пер.). В некоторых системах существуют другие типы блокировок. Фактически сама система DB2 внутренне поддерживает некоторые дополнительные их типы, но для пользователей в DB2 представляют интерес только блокировки типов Х и S.
3. Здесь рассматриваются только операции уровня записей (FETCH, UPDATE CURRENT и т. д.). Операции уровня множеств для целей блокирования могут рассматриваться как краткое обозначение соответствующих последовательностей операций уровня записей.
Теперь приступим к детальному рассмотрению вопроса.
1. Прежде всего если транзакция А устанавливает монопольную блокировку ( тип X) записи R, то запрос из транзакции В на любого типа блокировку записи R приведет к тому, что В перейдет в состояние ожидания. Транзакция В будет находиться в этом состоянии до тех пор, пока не будет снята блокировка, установленная транзакцией А.
2. Далее, если транзакция А устанавливает совместную блокировку (тип S) записи R, то: а) запрос из транзакции В на блокировку типа Х записи R заставит В перейти в состояние ожидания, и В будет находиться в этом состоянии до тех пор, пока не будет снята блокировка, установленная транзакцией А; б) запрос из транзакции В на блокировку типа S записи R будет удовлетворен, т. е. теперь транзакция В будет также удерживать блокировку типа S записи R.
Сказанное можно удобно резюмировать с помощью матрицы совместимости (рис. 11.5). Эта матрица интерпретируется следующим образом. Рассмотрим некоторую запись R. Предположим, что в настоящее время А удерживает блокировку R, тип которой указывается элементами в заголовках столбцов (тире обозначает отсутствие блокировки). Пусть теперь некоторая другая транзакция В издает запрос на блокировку R, тип которой указывается в левом столбце таблицы. Здесь для полноты снова включен случай «отсутствие блокировки». Тогда значение «N» на пересечении соответствующих столбца и строки матрицы указывает на конфликт—запрос транзакции В не может быть удовлетворен, и В переходит в состояние ожидания. Значение «Y» указывает совместимость — запрос В удовлетворяется. Очевидно, что приведенная матрица симметрична.
Х | S | — |
Х | N | N | Y |
Транзакция А | Время | Транзакция В |
— | — |
— | — |
FETCH R | t1 | — |
(установить блокировку | — |
типа S для R) | — |
— | t2 | FETCH R |
— | (установить блокировку |
— | типа S для R) |
— | — |
UPDATE R | t3 | — |
(запрос блокировки | — |
типа Х для R) | — |
ждать | t4 | UPDATE R |
ждать | (запрос блокировки |
ждать | типа Х для R) |
ждать | ждать |
ждать | ждать |
ждать | ждать |
Рис. 11.6. Не утрачиваются никакие обновления, но в момент t4 возникает тупиковая ситуация |
Транзакция А | Время | Транзакция В |
— | — |
— | — |
— | t1 | UPDATE R |
— | (запрос блокировки |
— | типа Х для R) |
FETCH R | t2 | — |
(запрос блокировки | — |
типа S для R) | — |
ждать | — |
t3 | точка синхронизации |
ждать | (снять блокировку типа |
Х для R) |
ждать | — |
повторно: FETCH R | t4 |
(установить блокировку |
типа S для R) |
— |
Рис. 11.7. Предотвращается ситуация, когда транзакция А «увидела» бы в момент t2 незафиксированное изменение |
Транзакция А | Время | Транзакция В |
— | — |
— | — |
— | t1 | UPDATE R |
— | (установить блокировку |
— | типа Х для R) |
UPDATE R | t2 | — |
(запрос блокировки | — |
типа Х для R) | — |
ждать | — |
ждать | t3 | точка синхронизации |
ждать | (снять блокировку типа |
Х для R) |
повторно: UPDATE R | t4 |
(установить блокировку |
типа Х для R) |
Рис. 11.8. Предотвращается ситуация, когда транзакция А обновила бы в момент t2 незафиксированное изменение Проблема анализа на противоречивость |
СЧЕТ 1 | СЧЕТ 2 | СЧЕТ 3 |
40 | 50 | 30 |
Транзакция А | Время | Транзакция В |
— | — |
— | — |
FETCH СЧЕТ 1 (40): | t1 | — |
(установить блокировку |
типа S для СЧЕТА 1): | — |
сумма = 40 | — |
— | — |
FETCH СЧЕТ 2 (50): | t2 | — |
(установить блокировку |
типа S для СЧЕТА 2): | — |
сумма = 90 | t3 | FETCH СЧЕТ 3 (30) |
— | (установить блокировку |
— | типа S для СЧЕТА 3): |
— | — |
— | t4 | UPDATE СЧЕТ 3 |
— | (установить блокировку |
— | типа Х для СЧЕТА З): |
— | 30®20 |
— |
— | t5 | FETCH СЧЕТ 1 (40) ( |
— | запрос блокировки) |
— | типа S для СЧЕТА 1 |
— | ждать |
— | t6 | UPDATE СЧЕТ 1 |
— | (установить блокировку |
— | типа Х для СЧЕТА 1) |
FETCH СЧЕТ 3 (20): | t7 | ждать |
(запрос блокировки | ждать |
S для СЧЕТА З): | ждать |
Ждать | ждать |
Ждать |
Рис. 11.9. Исключается анализ на противоречивость, но в момент t6 возникает тупиковая ситуация |