Теперь отменим транзакцию и выполним такой код:
--set
implicit_transactions on
--select
* from test_key with (serializable)
delete
from test_key with (serializable) where i = 4
--rollback
|
Здесь мы пытаемся удалить несуществующую строчку. В
соответствии с тем, что наш запрос должен выдавать всегда один и тот же
результат, менеджер блокировок должен обеспечить, что никакие другие транзакции
не смогут вставить какое-либо значение в диапазон от 3 до 5, а также изменить
граничные значения ключей на 4. Это достигается за счет установки разделяемой
блокировки обновления диапазона.
spid
|
dbid
|
ObjId
|
IndId
|
Type
|
Resource
|
Mode
|
Status
|
55
|
8
|
2009058193
|
2
|
KEY
|
(23005e3c905a)
|
RangeS-U
|
GRANT
|
55
|
8
|
2009058193
|
2
|
PAG
|
1:34
|
IU
|
GRANT
|
Если бы удаляемое значение было равно, например, 40, догадайтесь, какой диапазон был бы заблокирован менеджером блокировок. :) Он бы
заблокировал весь диапазон от 9 до положительной бесконечности. А что если бы
граничные значения ключа составляли бы не 3 и 5, а 9 и 500? Был бы заблокирован
диапазон от 9 до 500. Таковы требования высшего уровня изоляции транзакций!
Чтобы еще лучше усвоить правила блокировки диапазонов, попробуйте выполнить такой запрос:
--set
implicit_transactions on
select
* from test_key with (serializable) where i = 10
--delete
from test_key with (serializable) where i = 4
--rollback
|
Он приведет к установлению разделяемой блокировки на
диапазон от 9 до +INF, так что никакие операции вставки для этого диапазона не
смогут быть выполнены.
Блокировки схемы данных
Последний тип блокировок, рассматриваемых в этой
статье, связан с командами DDL и схемой данных (Schema). Блокировка схемы
(Schema lock) предназначена для блокирования метаданных объектов базы данных.
Типичной командой изменения таких данных может служить команда ALTER. Эта
команда приводит к изменению системных таблиц метаданных, таких, как
syscolumns, sysobjects, sysforeignkeys и других. Чтобы запретить другим
транзакциям обращаться к модифицируемым ресурсам и их метаданным, введены
блокировки схемы. Блокировки схемы бывают всего двух типов:
Блокировка стабильности схемы (Schema Stability Lock), обозначается Sch-S. Данный тип блокировки предназначен для гарантии
неизменности метаданных, но не самих данных. Т.е. блокировка стабильности схемы
– единственная из всех типов блокировок, совместимых с монопольной блокировкой.
В основном она устанавливается при компиляции тела запроса или хранимой
процедуры, на это время запрещается вносить изменения в схему данных, однако
разрешается устанавливать любой тип блокировок на сами данные, с которыми будет
работать компилируемый запрос.
Блокировка изменения схемы (Schema Modification Lock), обозначается Sch-M. Данный тип блокировки не совместим ни с каким другим типом, ни с самим собой. Устанавливается после внесения изменений в схему данных и
снимается после завершения транзакции.
Рассмотрим пример. В первой сессии выполните следующий
код:
begin
tran alter table test add another_field int
|
В таблице 11 приведено содержимое таблицы syslockinfo
для данной сессии.