45808 (Блокировки в MS SQL Server 2000), страница 6
Описание файла
Документ из архива "Блокировки в MS SQL Server 2000", который расположен в категории "". Всё это находится в предмете "информатика" из , которые можно найти в файловом архиве . Не смотря на прямую связь этого архива с , его также можно найти и в других разделах. Архив можно найти в разделе "рефераты, доклады и презентации", в предмете "информатика, программирование" в общих файлах.
Онлайн просмотр документа "45808"
Текст 6 страницы из документа "45808"
Блокировки схемы данных
Последний тип блокировок, рассматриваемых в этой статье, связан с командами 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 для данной сессии.
spid | dbid | ObjId | IndId | Type | Resource | Mode | Status |
55 | 8 | 0 | 0 | DB | S | GRANT | |
55 | 8 | 1 | 0 | TAB | IX | GRANT | |
55 | 8 | 3 | 0 | TAB | IX | GRANT | |
55 | 8 | 3 | 2 | KEY | (31038b3afd68) | X | GRANT |
55 | 8 | 1993058136 | 0 | TAB | Sch-M | GRANT | |
55 | 8 | 1 | 1 | KEY | (5800c7965d9d) | X | GRANT |
55 | 8 | 3 | 1 | KEY | (5b00f3711a81) | X | GRANT |
55 | 8 | 0 | 0 | DB | S | GRANT |
Давайте проанализируем четыре выделенные строчки:
Наложена монопольная блокировка ключа на объект с идентификатором 3. Это не что иное, как таблица syscolumns. Более подробную информацию об этом ключе можно получить, выполнив такой запрос:
select * from sysindexes where id = 3 and indid = 2 |
Наложена блокировка изменения схемы на объект с идентификатором 1993058136. Это не что иное, как таблица test.
Наложена монопольная блокировка ключа на объект с идентификатором 1. Это не что иное, как таблица sysobjects. Более подробную информацию об этом ключе можно получить, выполнив такой запрос:
select * from sysindexes where id = 1 and indid = 1 |
Наложена монопольная блокировка ключа c идентификатором 1 на объект с идентификатором 3. Подробную информацию об этом ключе можно получить, выполнив такой запрос:
select * from sysindexes where id = 3 and indid = 1 |
Еще один тип блокировки – Bulk Update – используется совместно с операциями массивного обновления. Он совместим только с блокировкой стабильности схемы и с самим собой.
Блокировки могут преобразовываться друг в друга по следующей схеме (рисунок 1).
Рисунок 1.
Таблица 12 показывает совместимость описанных типов блокировок друг с другом.
Тип | IS | S | U | IX | SIX | X | Sch-S | Sch-M | BU |
IS | + | + | + | + | + | - | + | - | - |
S | + | + | + | - | + | - | + | - | - |
U | + | + | - | - | - | - | + | - | - |
IX | + | + | - | + | - | - | + | - | - |
SIX | + | + | - | - | - | - | + | - | - |
X | - | - | - | - | - | - | + | - | - |
Sch-S | + | + | + | + | + | + | + | - | + |
Sch-M | - | - | - | - | - | - | - | - | - |
BU | - | - | - | - | - | - | + | - | + |
Хинты
Как уже говорилось ранее, для каждой сессии может быть выбран используемый по умолчанию уровень изоляции, действующий при выполнении любых команд T-SQL. Ниже я покажу, как это сделать.
Рассмотрим синтаксис команды установки уровня изоляции по умолчанию для текущего соединения.
SET TRANSACTION ISOLATION LEVEL { READ COMMITTED | READ UNCOMMITTED | REPEATABLE READ | SERIALIZABLE } |
READ UNCOMMITTED – устанавливает уровень изоляции транзакций, на котором решается проблема «грязной» записи;
READ COMMITTED – устанавливает уровень изоляции, на котором решается проблема «грязного» чтения;
REPEATABLE READ – устанавливает уровень изоляции, на котором решается проблема неповторяемого чтения;
SERIALIZABLE – устанавливает уровень изоляции, на котором решается проблема чтения фантомов.
Установка какого-либо значения остается действительной до конца сессии, или до тех пор, пока пользователь явно не изменит уровень изоляции транзакций.
Существует документированный способ просмотра текущего уровня изоляции с помощью команды DBCC USEROPTIONS, но лично я всегда пользуюсь более мощным, хотя и не документированным, средством. Чтобы узнать текущее значение изоляции, нужно воспользоваться таким скриптом:
dbcc traceon (3604) dbcc pss(1,53) dbcc traceoff (3604) |
Команда dbcc pss предназначена для вывода текущих настроек указанного в параметре соединения. Вот ее синтаксис:
DBCC pss( suid, spid, printopt = { 1 | 0 } ) |
suid – идентификатор пользователя (см. хранимую процедуру sp_helpuser);
spid – идентификатор серверного процесса;
printopt – флаг вывода (0 – стандартная информация, 1 – расширенная). По умолчанию 0.
Эта команда выводит много интересной информации, но для нас главное – выяснить текущий уровень изоляции. Для этого нужно среди выведенных многочисленных переменных найти одну с названием isolation_level. В моем случае она оказалась равна 0. Это говорит о том, что для данного соединения используется уровень изоляции по умолчанию, который, как я уже говорил, равен READ COMMITTED. Вот все значения, которые может принимать эта переменная:
0 – уровень изоляции по умолчанию (READ COMMITTED);
1 – уровень изоляции READ UNCOMMITTED;
2 – уровень изоляции READ COMMITTED;
3 – уровень изоляции REPEATABLE READ;
4 – уровень изоляции SERIALIZABLE.
Теперь рассмотрим, каким образом управлять уровнем изоляции транзакций на уровне отдельных команд. Вот синтаксис раздела FROM, который относится к нашей теме (все сказанное ниже относится не только к запросам, но и к командам изменения данных DELETE и UPDATE):
FROM { table_name [ [ AS ] table_alias ] [ WITH ( { INDEX ( index_val [ ,...n ] ) | FASTFIRSTROW | HOLDLOCK | NOLOCK | PAGLOCK | READCOMMITTED | READPAST | READUNCOMMITTED | REPEATABLEREAD | ROWLOCK | SERIALIZABLE | TABLOCK | TABLOCKX | UPDLOCK | XLOCK } |
Уровни READUNCOMMITTED и READCOMMITTED соответствуют одноименным уровням изоляции транзакций, только пишутся слитно. Блокировки при использовании этих уровней снимаются сразу после выполнения команды. В случае хинтов REPEATABLEREAD и SERIALIZABLE блокировки остаются до конца транзакции. Далее приводится подробное описание всех остальных хинтов.
FASTFIRSTROW – хинт не относится к блокировкам и уровням изоляции. Позволяет быстро выбрать первые строчки результирующего набора.
HOLDLOCK – аналогичен хинту SERIALIZABLE, т.е. устанавливает разделяемую блокировку диапазона индекса (если индекс существует) или простую разделяемую блокировку на страницу или таблицу. Оставлен для обратной совместимости.