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

Откуда: Москва
Сообщений: 19
Допустим:
Есть хранимая с двумя входными параметрами А и В.
Есть таблица с несколькими полями, среди которых есть поля А и В.

Необходимо:
При начале работы указанной хранимой происходит: либо блокировка диапазона ключа по значению А и В и дальнейшая работа хранимой, либо ожидание разблокирования указанного диапазона (в случае, если он был заблокирован транзакцией из параллельно выполняемой этой самой хранимой в другом процессе).

Вопрос:
Как?

Что было опробовано и в чем затруднения:
BEGIN TRAN
SELECT @Count = COUNT(*) FROM SomeTable WITH(UPDLOCK, SERIALIZABLE) WHERE A = @A AND B = @B

Но получается так, что хранимая с параметрами @A = 1 и @B = 2 ждет хранимую с параметрами @A = 3 и @B = 4, а по идее ждать должна только ту, у которой такие же значения параметров.

Первая транзакция получает блокировку типа KEY, ресурс (ffffffffffff), режим - RangeS-U. Вторая транзакция ждет точно такую же блокировку и не может ее получить, т.к. RangeS-U не совместима с RangeS-U.
Но блин, я думал, что сервер "запоминает" логическое условие A = 1 AND B = 2.

Пробую:
BEGIN TRAN
SELECT @Count = COUNT(*) FROM SomeTable WITH(HOLDLOCK, SERIALIZABLE) WHERE A = @A AND B = @B
Блокировки переходят в режим RangeS-S, а они совместимы друг с другом, поэтому этот селект перестает быть "забором", выполнение идет дальше, что потом приводит ко всяким deadlock.
21 май 04, 12:49    [692816]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка диапазона ключа  [new]
Sargos
Member

Откуда: Саратов
Сообщений: 563
Если не ошибаюсь, то по умолчанию блокируется страница целиком, а не конкретная запись в ней, можно попробывать ROWLOCK, если ресурсов хватит :)
Так если в условие попадет скажем 1000 строк, то чтобы их залочить придется наложить 1000 локов, вместо ..., сколько там у вас записей на страние помещается.
Кстати интересно, если запись по длине примерно страница, то разницы никакой?
21 май 04, 13:03    [692870]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка диапазона ключа  [new]
Aleskey
Member

Откуда: Москва
Сообщений: 19
Табличка сама не большая, записей не более сотни, четыре поля в сумме 33 байта..
Кстати, ROWLOCK он игнорирует. Упрямо ставит блокировку намерений на страницу.
21 май 04, 13:16    [692923]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка диапазона ключа  [new]
Aleskey
Member

Откуда: Москва
Сообщений: 19
В общем, условия задачи просты:
Заблокировать диапазон ключа. Любая транзакция, пытающаяся прочитать/изменить данные, попадающие в этот диапазон ДОЛЖНА ЖДАТЬ.

Пока у меня получается только так. Либо транзакция, работающая с этим диапазоном не ждет и ломится дальше, либо транзакция, работающая с другим диапазоном ждет!
Что не есть гуд в обоих случаях.
21 май 04, 13:30    [692974]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка диапазона ключа  [new]
ChA
Member

Откуда: Москва
Сообщений: 11125
Aleskey
Любая транзакция, пытающаяся прочитать/изменить данные, попадающие в этот диапазон ДОЛЖНА ЖДАТЬ

Простым способом для всех случаев не получится. Если читать с
NOLOCK, то какие бы блокировки не стояли, все равно прочитают.
Определитесь, в каких случаях нужно добиться такого эффекта,
тогда можно говорить о способе его достижения.

P.S. В некоторых случаях, когда мне нужно поставить выполнение
процедур(или их участков), грубо говоря, в очередь, использую
sp_getapplock
sp_releaseapplock.
21 май 04, 13:54    [693084]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка диапазона ключа  [new]
Alexes
Member

Откуда:
Сообщений: 1100
А составной индекс по A и B у вас есть?
BOL
Key-range locking ensures that these scenarios are serializable:
Range scan query
Singleton fetch of nonexistent row
Delete operation
Insert operation

However, the following conditions must be satisfied before key-range locking can occur:

The transaction-isolation level must be set to SERIALIZABLE.

The operation performed on the data must use an index range access. Range locking is activated only when query processing (such as the optimizer) chooses an index path to access the data.
21 май 04, 14:08    [693142]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка диапазона ключа  [new]
Aleskey
Member

Откуда: Москва
Сообщений: 19
автор
А составной индекс по A и B у вас есть?

Есть.
Я даже сделал первичный ключ по полю А и В. Но менеджер упорно блокирует весь диапазон (ffffffffffff).
21 май 04, 14:18    [693184]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка диапазона ключа  [new]
Merle
Guest
Но получается так, что хранимая с параметрами @A = 1 и @B = 2 ждет хранимую с параметрами @A = 3 и @B = 4, а по идее ждать должна только ту, у которой такие же значения параметров.
Не всегда, если индекс не уникальный, то a=3 и b=4 попадет в блокируемый диапазон, если этот ключ идет в индексе сразу за a=1 и b=2.

Первая транзакция получает блокировку типа KEY, ресурс (ffffffffffff), режим - RangeS-U
Такое может быть, если ключ a=1 и b=2, последний в индексе и "правее" его данных нет.

Если не ошибаюсь, то по умолчанию блокируется страница целиком,
Ошибаетесь.

Кстати, ROWLOCK он игнорирует. Упрямо ставит блокировку намерений на страницу.
rowlock не игнорирует - прочитайте про блокировки намерения, они здесь не при чем и rowlock в принципе не может оказать на них никакого влияния.
21 май 04, 19:12    [694217]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить