Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Зачем блокируются соседние записи на границе диапазона?  [new]
Андрей_Батькович
Member

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

Возможно вопрос чайниковский, но тем не менее не смог найти ответа, прошу грязными тряпками сразу не кидаться :)
Максимум что удалось найти, так это такой ответ " ... это особенность блокировочного механизма MS SQL".
Хотелось бы более подробно разобраться, почему при уровне изоляции SERIALIZABLE блокируется не только необходимый диапазон но и 2 соседние записи?

Например, в случае если есть записи:
1

2
3
4
5
6

7

и я блокирую записи по диапазону от 3 до 5 то будут заблокированы записи 2 и 6 т.к. они по соседству.
Объясните, зачем это нужно?!
30 авг 13, 14:16    [14776254]     Ответить | Цитировать Сообщить модератору
 Re: Зачем блокируются соседние записи на границе диапазона?  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
автор
и я блокирую записи по диапазону от 3 до 5 то будут заблокированы записи 2 и 6 т.к. они по соседству.


Это Вы:

1. На какой структуре таблицы и индексов;
2. На каком запросе, где "блокируете";
3. На каком запросе, где "проверяете что блокируется"

получили такой результат?
30 авг 13, 14:29    [14776341]     Ответить | Цитировать Сообщить модератору
 Re: Зачем блокируются соседние записи на границе диапазона?  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Андрей_Батькович
2 соседние записи?

Точно две записи? У меня только одна соседняя запись заблокировалась.

В одном окне SSMS выполняю:
use tempdb;
go

create table dbo.lock_test(id int primary key);

insert dbo.lock_test(id)
select 1 union all select 2 union all select 3 union all select 4
union all select 5 union all select 6 union all select 7;
go

begin transaction;

select * from dbo.lock_test with(xlock, holdlock) where id between 3 and 5;


В другом окне:
select * from dbo.lock_test with(xlock) where id = 2
— ОК, запись id = 2 не блокирована первым окном.
select * from dbo.lock_test with(xlock) where id = 6
— ожидание, запись id = 6 блокирована первым окном.

Смотрю блокировки:
select * from sys.dm_tran_locks where request_session_id = <spid первого окна>

resource_type resource_description request_mode
KEY (59855d342c69) RangeX-X
KEY (b9b173bbe8d5) RangeX-X
KEY (a0c936a3c965) RangeX-X
KEY (98ec012aa510) RangeX-X


Смотрю, к чему относятся хэши ключей:
select *, %%lockres%% as lockres
from dbo.lock_test with(nolock)
where %%lockres%% in ('(59855d342c69)', '(b9b173bbe8d5)', '(a0c936a3c965)', '(98ec012aa510)')

id lockres
3 (98ec012aa510)
4 (a0c936a3c965)
5 (59855d342c69)
6 (b9b173bbe8d5)

Действительно, не совсем понятно. Не обращал раньше внимания на такое поведение.
30 авг 13, 14:43    [14776445]     Ответить | Цитировать Сообщить модератору
 Re: Зачем блокируются соседние записи на границе диапазона?  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
Но если явно указать все значения из диапазона, то такой картины не будет:

select * from dbo.lock_test with(xlock, holdlock) WHERE id IN (3, 4, 5);


Предикаты, естественно, в операторе (Clustered)Index Seek будут разные.
30 авг 13, 15:16    [14776631]     Ответить | Цитировать Сообщить модератору
 Re: Зачем блокируются соседние записи на границе диапазона?  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
Гость333
Действительно, не совсем понятно.


Вот что есть в доке:

The number of RangeS-S locks held is n+1, where n is the number of rows that satisfy the query.

http://msdn.microsoft.com/en-us/library/ms191272(v=sql.105).aspx
30 авг 13, 15:24    [14776697]     Ответить | Цитировать Сообщить модератору
 Re: Зачем блокируются соседние записи на границе диапазона?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Ну там всё сложно. Как намекает pkarklin - зависит от типа операторов в запросе, сортировок (ASC DESC), ключей и т.п.
А в общем механизм next row - это стандартная фишка предотвращения фантомных записей.
1. Если записи вообще нет, тогда лаг надо закрыть, вот и хитрим через следующию запись
2. Может появится запись с таким же значением (если к примеру нет уникальности)
А вот если есть ключ, то возможно это связано с физическим внутренним порядком проведения самой операции, типа ограничения (и уникальности тоже) могут проверяются после физической вставки.

Почему не с обоих сторон? Ну потому что этого хватает, ибо другие запросы накроют свой кусок, и даже если сортировки разные - то жёстко определённый механизм работы не допустит.
30 авг 13, 15:28    [14776733]     Ответить | Цитировать Сообщить модератору
 Re: Зачем блокируются соседние записи на границе диапазона?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Тут более подробно.
30 авг 13, 15:35    [14776783]     Ответить | Цитировать Сообщить модератору
 Re: Зачем блокируются соседние записи на границе диапазона?  [new]
Андрей_Батькович
Member

Откуда:
Сообщений: 95
Спасибо
Действительно блокируется N+1 запись, хотя в документации по 1С написано что блокируются 2 соседние.
12 сен 13, 16:20    [14832245]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить