Фиктивные элементы (фантомы)

Транзакция A дважды выполняет выборку строк с одним и тем же условием. Между выборками вклинивается транзакция B, которая добавляет новую строку, удовлетворяющую условию отбора.

Транзакция A Время Транзакция B
S-блокировка строк, удовлетворяющих условию Фиктивные элементы (фантомы) - student2.ru . (Заблокировано n строк) Фиктивные элементы (фантомы) - student2.ru ---
Выборка строк, удовлетворяющих условию Фиктивные элементы (фантомы) - student2.ru . (Отобрано n строк) Фиктивные элементы (фантомы) - student2.ru ---
--- Фиктивные элементы (фантомы) - student2.ru Вставка новой строки, удовлетворяющей условию Фиктивные элементы (фантомы) - student2.ru .
--- Фиктивные элементы (фантомы) - student2.ru Фиксация транзакции
S-блокировка строк, удовлетворяющих условию Фиктивные элементы (фантомы) - student2.ru . (Заблокировано n+1 строка) Фиктивные элементы (фантомы) - student2.ru ---
Выборка строк, удовлетворяющих условию Фиктивные элементы (фантомы) - student2.ru . (Отобрано n+1 строк) Фиктивные элементы (фантомы) - student2.ru ---
Фиксация транзакции Фиктивные элементы (фантомы) - student2.ru ---
Появились строки, которых раньше не было    

Результат. Блокировка на уровне строк не решила проблему появления фиктивных элементов.

Собственно несовместимый анализ

Длинная транзакция выполняет некоторый анализ по всей таблице, например, подсчитывает общую сумму денег на счетах клиентов банка для главного бухгалтера. Пусть на всех счетах находятся одинаковые суммы, например, по $100. Короткая транзакция в этот момент выполняет перевод $50 с одного счета на другой так, что общая сумма по всем счетам не меняется.

Транзакция A Время Транзакция B
S-блокировка счета Фиктивные элементы (фантомы) - student2.ru - успешна Фиктивные элементы (фантомы) - student2.ru ---
Чтение счета Фиктивные элементы (фантомы) - student2.ru и суммирование. Фиктивные элементы (фантомы) - student2.ru Фиктивные элементы (фантомы) - student2.ru ---
--- Фиктивные элементы (фантомы) - student2.ru X-блокировка счета Фиктивные элементы (фантомы) - student2.ru - успешна
--- Фиктивные элементы (фантомы) - student2.ru Снятие денег со счета Фиктивные элементы (фантомы) - student2.ru . Фиктивные элементы (фантомы) - student2.ru
--- Фиктивные элементы (фантомы) - student2.ru X-блокировка счета Фиктивные элементы (фантомы) - student2.ru - отвергается
--- Фиктивные элементы (фантомы) - student2.ru Ожидание…
S-блокировка счета Фиктивные элементы (фантомы) - student2.ru - успешна Фиктивные элементы (фантомы) - student2.ru Ожидание…
Чтение счета Фиктивные элементы (фантомы) - student2.ru и суммирование. Фиктивные элементы (фантомы) - student2.ru Фиктивные элементы (фантомы) - student2.ru Ожидание…
S-блокировка счета Фиктивные элементы (фантомы) - student2.ru - отвергается Фиктивные элементы (фантомы) - student2.ru Ожидание…
Ожидание… Фиктивные элементы (фантомы) - student2.ru Ожидание…
Ожидание…   Ожидание…

Результат. Обе транзакции ожидают друг друга и не могут продолжаться. Возникла ситуация тупика.

Преднамеренные блокировки

Как видно из анализа поведения транзакций, при использовании протокола доступа к данным не решается проблема фантомов. Это происходит оттого, что были рассмотрены только блокировки на уровне строк. Можно рассматривать блокировки и других объектов базы данных:

  • Блокировка самой базы данных.
  • Блокировка файлов базы данных.
  • Блокировка таблиц базы данных.
  • Блокировка страниц (Единиц обмена с диском, обычно 2-16 Кб. На одной странице содержится несколько строк одной или нескольких таблиц).
  • Блокировка отдельных строк таблиц.
  • Блокировка отдельных полей.

Кроме того, можно блокировать индексы, заголовки таблиц или другие объекты.

Чем крупнее объект блокировки, тем меньше возможностей для параллельной работы. Достоинством блокировок крупных объектов является уменьшение накладных расходов системы и решение проблем, не решаемых с использованием блокировок менее крупных объектов. Например, использование монопольной блокировки на уровне таблицы, очевидно, решает проблему фантомов.

Современные СУБД, как правило, поддерживают минимальный уровень блокировки на уровне строк или страниц. (В старых версиях настольной СУБД Paradox поддерживалась блокировка на уровне отдельных полей.).

При использовании блокировок объектов разной величины возникает проблема обнаружения уже наложенных блокировок. Если транзакция A пытается заблокировать таблицу, то необходимо иметь информацию, не наложены ли уже блокировки на уровне строк этой таблицы, несовместимые с блокировкой таблицы. Для решения этой проблемы используется протокол преднамеренных блокировок, являющийся расширением протокола доступа к данным. Суть этого протокола в том, что перед тем, как наложить блокировку на объект (например, на строку таблицы), необходимо наложить специальную преднамеренную блокировку (блокировку намерения) на объекты, в состав которых входит блокируемый объект - на таблицу, содержащую строку, на файл, содержащий таблицу, на базу данных, содержащую файл. Тогда наличие преднамеренной блокировки таблицы будет свидетельствовать о наличии блокировки строк таблицы и для другой транзакции, пытающейся блокировать целую таблицу не нужно проверять наличие блокировок отдельных строк. Более точно, вводятся следующие новые типы блокировок:

  • Преднамеренная блокировка с возможностью взаимного доступа (IS-блокировка - Intent Shared lock). Накладывается на некоторый составной объект T и означает намерение блокировать некоторый входящий в T объект в режиме S-блокировки. Например, при намерении читать строки из таблицы T, эта таблица должна быть заблокирована в режиме IS (до этого в таком же режиме должен быть заблокирован файл).
  • Преднамеренная блокировка без взаимного доступа (IX-блокировка - Intent eXclusive lock). Накладывается на некоторый составной объект T и означает намерение блокировать некоторый входящий в T объект в режиме X-блокировки. Например, при намерении удалять или модифицировать строки из таблицы T эта таблица должна быть заблокирована в режиме IX (до этого в таком же режиме должен быть заблокирован файл).
  • Преднамеренная блокировка как с возможностью взаимного доступа, так и без него (SIX-блокировка - Shared Intent eXclusive lock). Накладывается на некоторый составной объект T и означает разделяемую блокировку всего этого объекта с намерением впоследствии блокировать какие-либо входящие в него объекты в режиме X-блокировок. Например, если выполняется длинная операция просмотра таблицы с возможностью удаления некоторых просматриваемых строк, то можно заблокировать эту таблицу в режиме SIX (до этого захватить файл в режиме IS).

IS, IX и SIX-блокировки должны накладываться на сложные объекты базы данных (таблицы, файлы). Кроме того, на сложные объекты могут накладываться и блокировки типов S и X. Для сложных объектов (например, для таблицы базы данных) таблица совместимости блокировок имеет следующий вид:



  Транзакция B пытается наложить на таблицу блокировку:
Транзакция A наложила на таблицу блокировку: IS S IX SIX X
IS Да Да Да Да Нет
  Да Да Нет Нет Нет
IX Да Нет Да Нет Нет
SIX Да Нет Нет Нет Нет
X Нет Нет Нет Нет Нет

Таблица 2 Расширенная таблица совместимости блокировок

Более точная формулировка протокола преднамеренных блокировок для доступа к данным выглядит следующим образом:

  1. При задании X-блокировки для сложного объекта неявным образом задается X-блокировка для всех дочерних объектов этого объекта.
  2. При задании S- или SIX-блокировки для сложного объекта неявным образом задается S-блокировка для всех дочерних объектов этого объекта.
  3. Прежде чем транзакция наложит S- или IS-блокировку на заданный объект, она должна задать IS-блокировку (или более сильную) по крайней мере для одного родительского объекта этого объекта.
  4. Прежде чем транзакция наложит X-, IX- или SIX-блокировку на заданный объект, она должна задать IX-блокировку (или более сильную) для всех родительских объектов этого объекта.
  5. Прежде чем для данной транзакции будет отменена блокировка для данного объекта, должны быть отменены все блокировки для дочерних объектов этого объекта.

Понятие относительной силы блокировок можно описать при помощи следующей диаграммы приоритета (сверху - более сильные блокировки, снизу - более слабые):

Фиктивные элементы (фантомы) - student2.ru

Таблица 3 Диаграмма приоритета блокировок

Замечание. Протокол преднамеренных блокировок не определяет однозначно, какие блокировки должны быть наложены на родительский объект при блокировании дочернего объекта. Например, при намерении задать S-блокировку строки таблицы, на таблицу, включающую эту строку, можно наложить любую из блокировок типа IS, S, IX, SIX, X. При намерении задать X-блокировку строки, на таблицу можно наложить любую из блокировок типа IX, SIX, X.

Посмотрим, как разрешается бпроблема фиктивных элементов (фантомов) с использованием протокола преднамеренных блокировок для доступа к данным.

Транзакция A дважды выполняет выборку строк с одним и тем же условием. Между выборками вклинивается транзакция B, которая добавляет новую строку, удовлетворяющую условию отбора.

Транзакция B перед попыткой вставить новую строку должна наложить на таблицу IX-блокировку, или более сильную (SIX или X). Тогда транзакция A, для предотвращения возможного конфликта, должна наложить такую блокировку на таблицу, которая не позволила бы транзакции B наложить IX-блокировку. По таблице совместимости блокировок определяем, что транзакция A должна наложить на таблицу S, или SIX, или X-блокировку. (Блокировки IS недостаточно, т.к. эта блокировка позволяет транзакции B наложить IX-блокировку для последующей вставки строк).

Транзакция A Время Транзакция B
S-блокировка таблицы (с целью потом блокировать строки) – успешна Фиктивные элементы (фантомы) - student2.ru ---
S-блокировка строк, удовлетворяющих условию Фиктивные элементы (фантомы) - student2.ru . (Заблокировано n строк) Фиктивные элементы (фантомы) - student2.ru ---
Выборка строк, удовлетворяющих условию Фиктивные элементы (фантомы) - student2.ru . (Отобрано n строк) Фиктивные элементы (фантомы) - student2.ru ---
--- Фиктивные элементы (фантомы) - student2.ru IX-блокировка таблицы (с целью потом вставлять строки) - отвергается из-за конфликта с S-блокировкой, наложенной транзакцией A
--- Фиктивные элементы (фантомы) - student2.ru Ожидание…
--- Фиктивные элементы (фантомы) - student2.ru Ожидание…
S-блокировка строк, удовлетворяющих условию Фиктивные элементы (фантомы) - student2.ru . (Заблокировано n строк) Фиктивные элементы (фантомы) - student2.ru Ожидание…
Выборка строк, удовлетворяющих условию Фиктивные элементы (фантомы) - student2.ru . (Отобрано n строк) Фиктивные элементы (фантомы) - student2.ru Ожидание…
Фиксация транзакции - блокировки снимаются Фиктивные элементы (фантомы) - student2.ru Ожидание…
--- Фиктивные элементы (фантомы) - student2.ru IX-блокировка таблицы (с целью потом вставлять строки) - успешна
--- Фиктивные элементы (фантомы) - student2.ru Вставка новой строки, удовлетворяющей условию Фиктивные элементы (фантомы) - student2.ru .
--- Фиктивные элементы (фантомы) - student2.ru Фиксация транзакции
Транзакция A дважды читает один и тот же набор строк Все правильно    

Результат. Проблема фиктивных элементов (фантомов) решается, если транзакция A использует преднамеренную S-блокировку или более сильную.

Замечание. Т.к. транзакция A собирается только читать строки таблицы, то минимально необходимым условием в соответствии с протоколом преднамеренных блокировок является преднамеренная IS-блокировка таблицы. Однако этот тип блокировки не предотвращает появление фантомов. Таким образом, транзакцию A можно запускать с разными уровнями изолированности - предотвращая или допуская появление фантомов. Причем, оба способа запуска соответствуют протоколу преднамеренных блокировок для доступа к данным

Наши рекомендации