РУКОВОДСТВО ПО РЕЛЯЦИОННОЙ СУБД DB2

         

КАК СИСТЕМА 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



Х

S



N

N

Y

N

Y

Y

Y

Y

Y

Рис. 11.5. Матрица совместимости типов блокировки

Продолжим наше рассмотрение.

3. Запросы транзакций на блокировку записей всегда являются неявными. Когда транзакция успешно осуществляет выборку записи (операция FETCH), она автоматически устанавливает блокировку типа S этой записи. Когда транзакция успешно обновляет запись, она автоматически устанавливает блокировку типа Х этой записи. Если же она уже удерживала блокировку типа Х для этой записи, как это будет происходить в случае последовательности операций FETCH . . . UPDATE, то операция UPDATE «повышает» блокировку типа S до уровня X.



4. Блокировки типа Х удерживаются до следующей точки синхронизации. Блокировки типа S обычно также удерживаются до этого момента времени (см. однако обсуждение вопроса об уровне изоляции в разделе 11.6).

Теперь мы имеем возможность уяснить, каким образом в системе DB2 решаются три проблемы, описанные в предыдущем разделе. Снова будем рассматривать их поочередно.

Проблема утраченного обновления

Рис. 11.6 представляет собой модифицированный вариант рис. 11.1, показывающий, что произошло бы при параллельном" исполнении приведенных на рисунке транзакций под управлением механизма блокирования, предусмотренного в системе DB2.

Транзакция А

Время

Транзакция В









FETCH R

t1



(установить блокировку



типа S для R)





t2

FETCH R



(установить блокировку



типа S для R)





UPDATE R

t3



(запрос блокировки



типа Х для R)



ждать

t4

UPDATE R

ждать

(запрос блокировки

ждать

типа Х для R)

ждать

ждать

ждать

ждать

ждать

ждать

Рис. 11.6. Не утрачиваются никакие обновления, но в момент t4 возникает тупиковая ситуация

Легко видеть, что запрос транзакции А в момент t3 на операцию UPDATЕ не принимается, поскольку это неявный запрос на блокировку типа Х для записи R, и такой запрос противоречит блокировке типа S, уже установленной транзакцией В. Поэтому А переходит в состояние ожидания. По аналогичным причинам транзакция В переходит в состояние ожидания в момент t4. Теперь обе транзакции не могут быть продолжены. Поэтому не возникает вопрос о том, что какое-либо обновление может быть утрачено. Таким образом, в системе DB2 проблема утраченного обновления решается путем сведения ее к другой проблеме, но это, по крайней мере, действительно решает первоначальную проблему! Эта новая проблема  называется проблемой тупиковых ситуаций. Решение этой проблемы в системе DB2 обсуждается в разделе 11.7.



Проблема зависимости от незафиксированных обновлений

Рис. 11.7 и 11. 8 являются модифицированными вариантами рис. 11.2 и 11.3 соответственно, показывающими, что произошло бы при параллельном исполнении представленных на этих рисунках транзакций под управлением механизма блокирования, используемого в системе DB2. Нетрудно видеть, что операция транзакции А, запрашиваемая в момент t2 (FETCH—на рис. 11.7 и UPDATE—на рис. 11.8), в обоих случаях не выполняется, поскольку это неявный запрос на блокировку R, а такой запрос вступает в конфликт с уже установленной транзакцией В блокировкой типа X. Поэтому А переходит в состояние ожидания. Она остается в этом состоянии до тех пор, пока В не достигнет точки синхронизации, выполняя операцию COMMIT или ROLLBACK. При этом установленная транзакцией В блокировка снимается, и А получает возможность продолжать исполнение. В этот момент А «видит» зафиксированное значение — либо значение, предшествующее исполнению В, если В завершается операцией ROLLBACK, либо значение, соответствующее успешному завершению В, в противном случае. В любом случае А больше не зависит от незафиксированных обновлений.

Транзакция А

Время

Транзакция В











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 возникает тупиковая ситуация

Рис. 11.9—это модифицированный вариант рис. 11.4, показывающий, что произошло бы при параллельном исполнении представленных на этом рисунке транзакций под управлением механизма блокирования, который используется в системе DB2. Нетрудно видеть, что запрос транзакции В на операцию UPDATE и момент t6 не принимается, поскольку он является неявным запросом на блокировку типа Х для СЧЕТА 1, а такой запрос вступает в конфликт с блокировкой типа S, уже установленной транзакцией А. Поэтому В переходит в состояние ожидания. Подобным же образом в момент t7 не принимается также запрос транзакции А на выполнение операции FETCH, так как он является неявным запросом на установление блокировки типа S для СЧЕТА 3, а такой запрос вступает в конфликт с блокировкой типа X, уже установленной транзакцией В. По этой причине А также переходит в состояние ожидания. Итак, снова первоначальная проблема (в данном случае, проблема анализа на противоречивость) решается в системе DB2 путем форсирования возникновения тупиковой ситуации. Как уже говорилось, проблема тупиковых ситуаций обсуждается в разделе 11.7.


Содержание раздела