Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Наложение lock-ов по критерию запроса в isolation level serializable транзакциях  [new]
Dmitry Gurianov
Member

Откуда:
Сообщений: 651
Всем привет!

Про isolation level serializable документация пишет :

автор
Блокировка диапазона устанавливается в диапазоне значений ключа, соответствующих условиям поиска любой инструкции, выполненной во время транзакции. Обновление и вставка строк, удовлетворяющих инструкциям текущей транзакции, блокируется для других транзакций.

У меня есть тестовая таблица TEST с полями ID (PK) и NAME.

Процесс А выбирает запись по первичному ключу:

set transaction isolation level serializable
begin tran 
	select * from test where id = 1
	waitfor delay '00:00:10'
commit


Процесс Б пытается сделать обновление той же записи:

update test set name = '111' where id = 1


и, разумеется, обламывается, ожидая, пока процесс А завершит работу.
При этом, альтернативная инструкция процесса Б

update test set name = '111' where id = 2


отработает нормально, ибо ее ключ не подпадает под ключи в запросе процесса А.
Это понятно и прекрасно. Но если в качестве критерия выборки в процессе А поставить не первичный ключ, а другое поле:

set transaction isolation level serializable
begin tran 
	select * from test where name = 'aaa'
	waitfor delay '00:00:10'
commit


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

update test set name = '111' where name = 'bbb'


все равно повиснет, ожидая завершение процесса А.

Вопрос №1: я правильно понимаю, что заявленная для SERIALIZE блокировка по критериям работает для полей типа Primary или Unique key, а если в критерии выборки не участвуют ключи, то ко всей таблице?
Вопрос №1: Что делать, если я хочу накладывать lock-и по неключевым критериям? Например, если хочу наложить локи только на записи с name='aaa'.

Спасибо!
19 апр 12, 13:37    [12438994]     Ответить | Цитировать Сообщить модератору
 Re: Наложение lock-ов по критерию запроса в isolation level serializable транзакциях  [new]
iljy
Member

Откуда:
Сообщений: 8711
Dmitry Gurianov,

блокировка ориентируется на операции Index/Table Seek, соответственно диапазон ключа берется из параметров этих операций. Поиск по неиндексированному полю приводит к сканированию всей таблицы/индекса, соответственно и блокируется все.
19 апр 12, 13:42    [12439044]     Ответить | Цитировать Сообщить модератору
 Re: Наложение lock-ов по критерию запроса в isolation level serializable транзакциях  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Ну так посмотрите, какие блокировки накладывает ваша транзакция.

З.Ы. Range-блокировки - они на самом деле "Key-range locks". Если вы будете писать условие, которое не попадает в индекс, то, скорее всего, плоучите Range-lock на весь диапазон PK.

Key-Range Locking ( ms-help://MS.SQLCC.v10/MS.SQLSVR.v10.en/s10de_1devconc/html/eb488736-2fb7-4d0e-a347-e8e411ee6cd3.htm )
The query processor must use an index to implement the range filter predicate. For example, the WHERE clause in a SELECT statement could establish a range condition with this predicate: ColumnX BETWEEN N'AAA' AND N'CZZ'. A key-range lock can only be acquired if ColumnX is covered by an index key.
19 апр 12, 13:46    [12439086]     Ответить | Цитировать Сообщить модератору
 Re: Наложение lock-ов по критерию запроса в isolation level serializable транзакциях  [new]
Dmitry Gurianov
Member

Откуда:
Сообщений: 651
iljy
Dmitry Gurianov,

блокировка ориентируется на операции Index/Table Seek, соответственно диапазон ключа берется из параметров этих операций. Поиск по неиндексированному полю приводит к сканированию всей таблицы/индекса, соответственно и блокируется все.


Спасибо! Я тут как раз добрел до BOL, где все красиво про блокировки сказано. Крутанская вещь :)
19 апр 12, 13:47    [12439088]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить