ВОЗМОЖНОСТИ ЯВНОГО БЛОКИРОВАНИЯ
Помимо механизма неявного блокирования, описанного в предыдущем разделе, система DB2 обеспечивает некоторые явные возможности, о которых программист должен быть по меньшей мере осведомлен, хотя в большинстве ситуаций будет достаточно неявных возможностей. Средства явного блокирования в некоторой мере неоднородны и состоят из 1) предложения LOCK TABLE (блокировать таблицу) языка SQL, 2) факультативного параметра уровня изоляции в команде BIND и 3) параметра «единица блокирования» табличного пространства.
Предложение LOCK TABLE
Предложение LOCK TABLE языка SQL имеет следующий формат:
LOCK TABLE имя—таблицы IN режим MODE;
где «режим» может специфицироваться как SHARE (совместный) или EXCLUSIVE (монопольный), «имя—таблицы» должно обозначать базовую таблицу, а не представление. Например:
LOCK TABLE SP IN EXCLUSIVE MODE;
Это предложение устанавливает блокировку типа Х для всей базовой таблицы SP в интересах издающей его транзакции. Конечно, эта транзакция, возможно, должна будет ждать до тех пор, пока она сможет установить эту блокировку, если некоторая другая транзакция ранее уже установила блокировку, противоречащую данной. Как только указанная блокировка будет установлена, никакая другая транзакция не сможет обращаться каким-либо образом к любой части этой таблицы до тех пор, пока не будет снята первоначальная блокировка. Эта блокировка не будет снята, пока не завершится данная программа[21]
(а не транзакция).
Если вместо EXCLUSIVE специфицируется SHARE, то данная транзакция будет, конечно, устанавливать блокировку типа S, а не типа X. При этом другие транзакции не смогут установить блокировку типа Х для рассматриваемой таблицы или какой-либо се части до тех пор, пока не будет снята первоначальная блокировка. Однако до этого момента времени они смогут устанавливать блокировку типа S для данной таблицы или некоторой ее части.
Назначение предложения
LOCK TABLE состоит в следующем. Если транзакция обращается к большому числу отдельных записей и поочередно блокирует их, как было описано в предыдущем разделе, то накладные расходы на блокирование для этой транзакции могут быть весьма высокими в отношении как пространства, так и времени—пространства для удержания блокировок к основной памяти, а времени — для их установки. Рассмотрим, например, программу, которая просматривает всю таблицу поставок и печатает ее. Для такой программы, вероятно, лучше установить единственную блокировку на уровне таблицы, как в приведенном выше примере, и таким образом полностью обойтись для этой таблицы без необходимости блокировок на уровне записей. Это делается, конечно, в ущерб параллелизму, однако производительность данной отдельной транзакции будет повышаться и, возможно, в такой степени, что будет также повышаться суммарная производительность системы.
Установление блокировки типа Х на уровне таблицы действительно позволит полностью обойтись без необходимости блокировок на уровне записей для рассматриваемой таблицы, как было только что сказано. Установление же блокировки типа S на уровне таблицы избавит от блокировок типа Х на уровне записей (опять-таки для рассматриваемой таблицы). В самом деле, если программа обновляет какую-либо запись в данной таблице, ей все же потребуется установить блокировку типа Х для этой конкретной записи, благодаря чему параллельные транзакции будут лишены возможности «увидеть» незафиксированное изменение.
Примечание. Хотя операция LOCK TABLE определяется, конечно, как блокирование базовой таблицы, фактически система DB2 блокирует табличное пространство, которое содержит эту таблицу (см. главу 13).
Уровень изоляции
Уровень изоляции — это свойство плана прикладной задачи. Оно специфицируется с помощью параметра команды BIND, которая продуцирует этот план. Имеются два возможных значения этого параметра: RR («повторяемое чтение») и CS («стабильноcть курсора»), причем RR—значение, которое принимается по умолчанию.
Указанные значения параметра имеют следующий смысл:
— «Стабильность курсора» означает, что если использующая этот план транзакция:
а) получает возможность доступа к некоторой конкретной записи путем установки курсора так, чтобы он указывал эту запись, и таким образом
б) устанавливает для этой записи блокировку типа S, а затем
в) отказывается от возможности доступа к этой записи, не обновляя ее, и поэтому
г) не повышает ее блокировку типа S до уровня X, то
д) можно снять эту блокировку типа S, не обязательно дожидаясь следующей точки синхронизации.
— «Повторяемое чтение» означает, что блокировки типа S на уровне записей удерживаются до следующей точки синхронизации подобно блокировкам типа X. Уровень изоляции CS может обеспечить несколько большую степень параллелизма, чем уровень изоляции RR, но вообще это не очень хороший вариант. Именно поэтому по умолчанию принимается значение RR. Проблема, связанная со значением CS, состоит в том, что для транзакции, оперирующей на этом уровне, запись может быть изменена «у нее за спиной», как показано на рис. 11.4, и поэтому такая транзакция может продуцировать неверный ответ. Фактически, если транзакция оперирует на уровне изоляции CS, то теоретически всегда возможно определить вторую транзакцию, которая может исполняться параллельно с первой таким образом, чтобы продуцировать некорректный общий результат. Напротив, транзакция, оперирующая на уровне изоляции RR, может вести себя совершенно так, как если бы она исполнялась в системе с единственным пользователем.
Заметим, что хотя уровень изоляции специфицируется как часть команды BIND, а не как часть программы, программисту все же необходимо быть о нем осведомленным, поскольку от значения этого параметра может зависеть логика программы, иначе говоря, оно может влиять на способ, которым должна кодироваться программа.
Параметр «единица блокирования» табличного пространства
Этот вопрос здесь затрагивается только для полноты рассмотрения. Следующее описание, вероятно, не будет иметь большого смысла до тех пор, пока читатель не изучит главу 13.
Как указывалось в разделе 11.5, механизм неявного блокирования в системе DB2 определяется в терминах блокировок уровня записей. Однако это логическое
определение. Физически DB2 блокирует данные в терминах страниц или табличных пространств. Иначе говоря, когда заданная транзакция логически блокирует некоторую отдельную запись, система DB2 физически блокирует либо страницу, либо табличное пространство, которое содержит эту запись, в зависимости от того, что было специфицировано для этого табличного пространства в запросе, когда оно создавалось.
Для любого заданного табличного пространства может быть специфицирован в качестве «единицы блокирования» один из следующих вариантов: PAGE (страница), TABLESPACE (табличное пространство) или ANY (любой из предшествующих вариантов). При этом:
— ANY (вариант по умолчанию) означает, что DB2 сама будет решать вопрос о подходящей физической единице блокирования для табличного пространства каждого плана, т. е. для одного и того же табличного пространства один план может устанавливать блокировки на уровне страниц, в то время как другой устанавливает их на уровне табличного пространства.
— TABLESPACE означает, что все блокировки, устанавливаемые на данные в этом табличном пространстве, будут осуществляться на уровне табличного пространства.
— PAGE означает, что в заданном табличном пространстве блокировки данных будут всякий раз, когда это возможно, устанавливаться на уровне страниц. Однако иногда DB2 будет все же устанавливать блокировки на уровне табличного пространства. Детальное рассмотрение этого вопроса выходит за рамки данной работы.