Несмотря
на привлекательность метода гранулированных синхронизационных захватов, следует
отметить, что он не решает проблему фантомов (если, конечно, не ограничиться
использованием захватов отношений в режимах S и X).
Известно,
что проблема фантомов не возникает, если объектом блокировки является целое
отношение. Именно это свойство и послужило основой разработки метода
предикатных синхронизационных захватов. В этом случае мы рассматриваем захват
отношения — простой и частный случай предикатного захвата.
Суть этого
метода — оценить множество кортежей, которое связано с той или иной транзакций,
и если эти два множества, относящиеся к одному отношению, не пересекаются, то
две транзакции могут оперировать ими параллельно без взаимной блокировки, а
результаты выполнения обеих транзакций будут корректными.
Поскольку
любая операция над реляционной базой данных задается некоторым условием (то
есть в ней указывается не конкретный набор объектов базы данных, над которыми
нужно выполнить операцию, а условие, которому должны удовлетворять объекты этого
набора), идеальным выбором было бы требовать синхронизационный захват в режиме
S или X именно этого условия. Но если посмотреть на общий вид условий, допускаемых,
например, в языке SQL, то становится абсолютно непонятно, как определить совместимость
двух предикатных захватов. Ясно, что без этого использовать предикатные захваты
для синхронизации транзакций невозможно, а в общей форме проблема неразрешима.
К счастью,
эта проблема сравнительно легко решается для случая простых условий. Будем называть
простым условием конъюнкцию простых предикатов, имеющих вид:
имя-атрибута
{ операция сравнения } значение
Здесь операция
сравнения: =, >, <
В типичных
СУБД, поддерживающих двухуровневую организацию (языковой уровень и уровень управления
внешней памяти), в интерфейсе подсистем управления памятью (которая обычно заведует
и сериализацией транзакций) допускаются только простые условия. Подсистема языкового
уровня производит компиляцию исходного оператора со сложным условием в последовательность
обращений к ядру СУБД, в каждом из которых содержатся только простые условия.
Следовательно, в случае типовой организации реляционной СУБД простые условия
можно использовать как основу предикатных захватов.
Для простых
условий совместимость предикатных захватов легко определяется на основе следующей
геометрической интерпретации. Пусть R — отношение с атрибутами а1,
а2, ..., аn, а m1,m2, ..., mn
— множества допустимых значений а1, а2, ..., аn
соответственно (все эти множества — конечные). Тогда можно сопоставить R конечное
n-мерное пространство возможных значений кортежей R. Любое простое условие «вырезает»
m-мерный прямоугольник в этом пространстве (m <= n).
Тогда S-X,
X-S, X-Х предикатные захваты от разных транзакций совместимы, если соответствующие
прямоугольники не пересекаются.
Это иллюстрируется
следующим примером, показывающим, что в каких бы режимах не требовала транзакция
1 захвата условия (1<=а<=4) & (b=5), а транзакция 2 — условия (1<=а<=5)
& (1<=b<=3), эти захваты всегда совместимы.
Пример: (n
= 2)
Заметим,
что предикатные захваты простых условий описываются таблицами, немногим отличающимися
от таблиц традиционных синхронизаторов.
Рис.
11.13. Области действия предикатных захватов