Практически во всех ведущих СУБД для обработки параллельных транзакций применяется довольно сложный механизм блокировки. Однако принципы блокировки транзакций довольно просты. На, нижеследующем рисунке изображена схема простой блокировки, устраняющей конфликты между двумя параллельными транзакциями.
Когда транзакция А обращается к базе данных, СУБД автоматически блокирует все части базы данных, в которых транзакция осуществляет выборку или изменение. Транзакция B выполняется параллельно, и СУБД также блокирует те части базы данных, к которым она обращается. Если транзакция B обращается к той части базы данных, которая заблокирована транзакцией А, то СУБД приостанавливает выполнение транзакции B, заставляя ее ждать до тех пор, пока данные не будут разблокированы. СУБД снимает блокировку, вызванную транзакцией А, только после того, как в этой транзакции встретится инструкция COMMIT или ROLLBACK. Затем СУБД позволяет продолжить выполнение транзакции B. Теперь транзакция B блокирует эту же часть базы данных, защищая ее от других транзакций.
Рисунок 29 Блокировка при одновременном выполнении
двух транзакций
Как видно из рисунка, при блокировке транзакция временно получает монопольный доступ к некоторой части базы данных, причем другим транзакциям запрещается изменять заблокированные данные. Таким образом, блокировка решает все проблемы, возникающие при параллельном выполнении транзакций. Она не допускает разрушения базы данных в результате потери обновлений и использования промежуточных или несогласованных данных. Однако блокировка создает новую проблему: период времени, в течение которого транзакция ожидает освобождения части базы данных, заблокированной другой транзакцией, может быть достаточно большим.
В базе данных блокировка может быть реализована на различных уровнях. Самой грубой формой блокировки является блокировка всей базы данных. Этот вид блокировки легко реализовать, но при этом в каждый момент времени можно будет выполнять только одну транзакцию. Если транзакция затрачивает некоторое время “на размышления” (например, время обсуждения заказа с клиентом), то доступ всех остальных пользователей к базе данных будет при этом заблокирован, что приводит к слишком низкой производительности.
Другой формой блокировки является блокировка на уровне таблиц. В этом случае СУБД блокирует только те таблицы, к которым обращается транзакция. Остальные транзакции в это время могут обращаться к другим таблицам. Этот вид блокировки предпочтительнее, чем блокировка базы данных, поскольку он позволяет проводить параллельную обработку транзакций. Но в таких приложениях, как программы для ввода заказов, в которых несколько пользователей одновременно обращаются к одним и тем же таблицам, данный вид блокировки также приводит к слишком низкой производительности.
Во многих СУБД реализована блокировка на уровне страниц. В этом случае СУБД блокирует отдельные блоки данных на диске (“страницы”), когда транзакция обращается к ним. Остальным транзакциям запрещается доступ к заблокированным страницам, но они могут обращаться к другим страницам данных (и блокировать их для себя). Обычно используются страницы размером 2, 4 и 16 Кб. Поскольку большая таблица состоит из множества страниц, две транзакции, обращающиеся к двум различным строкам таблицы, как правило, обращаются к различным страницам; в результате обе транзакции выполняются параллельно.
За последние несколько лет в большинстве ведущих СУБД была реализована блокировка на уровне строк. Она допускает параллельное выполнение транзакций, которые обращаются к двум различным строкам таблицы, даже если эти строки содержатся на одной странице. Хотя такая возможность кажется несущественной, в случае таблиц, содержащих небольшое число строк, она может играть важную роль.
Блокировка на уровне строк обеспечивает параллельное выполнение большого количества транзакций. К сожалению, осуществить блокировку строк различной длины гораздо сложнее, чем блокировку страниц фиксированного размера, поэтому повышение параллелизма работы обеспечивается за счет усложнения логики блокирования и роста накладных расходов. Тем не менее, поставщики СУБД, которые делают упор на оперативную обработку транзакций, все более широко применяют такой режим блокировки. Часто имеется возможность выбора типа блокировки: на уровне страниц или на уровне строк.
В настоящее время проблема блокировки является предметом большого числа исследований. Сложность механизмов блокировки, используемых в коммерческих СУБД, намного превышает сложность основных схем блокировки, описанных выше. В следующем параграфе рассматривается наиболее простой из этих механизмов, основанный на применении жесткой и нежесткой блокировок.