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

Откуда:
Сообщений: 70
Добрый день!

Занимаюсь изучением оптимизации производительности промышленных СУБД и наткнулся на не совсем понятный для себя момент: U блокировки.
MSDN
В сериализуемой транзакции или транзакции с повторяющимся чтением транзакция считывает данные, запрашивает совмещаемую (S) блокировку на ресурс (страницу или строку), затем выполняет изменение данных, что требует преобразование блокировки в монопольную (X). Если две транзакции запрашивают совмещаемую блокировку на ресурс и затем пытаются одновременно обновить данные, то одна из транзакций пытается преобразовать блокировку в монопольную (X). Преобразование совмещаемой блокировки в монопольную потребует некоторого времени, поскольку монопольная блокировка для одной транзакции несовместима с совмещаемой блокировкой для другой транзакции. Начнется ожидание блокировки. Вторая транзакция попытается получить монопольную (X) блокировку для обновления. Поскольку обе транзакции выполняют преобразование в монопольную (X) блокировку и при этом каждая из транзакций ожидает, пока вторая снимет совмещаемую блокировку, то в результате возникает взаимоблокировка.

Чтобы избежать этой потенциальной взаимоблокировки, применяются блокировки обновления (U). Блокировку обновления (U) может устанавливать для ресурса одновременно только одна транзакция. Если транзакция изменяет ресурс, то блокировка обновления (U) преобразуется в монопольную (X) блокировку.

То есть, пока U блокировка не преобразована в X, другие транзакции могут приобретать S блокировки. Если требуется преобразовать U в X, СУБД подождет, пока не снимутся S блокировки других транзакций. Но, что будет, если другая транзакция после S затребует X блокировку, как в примере? По-моему все равно должна возникнуть взаимная блокировка. Тогда в чем смысл было городить эту блокировку? Как я себе это могу объяснить, U блокировки придумали специально для запросов типа UPDATE, и запросов с соответствующим хинтом (SELECT FOR UPDATE, ...), т.к. эти запросы, требуя U блокировку вместо последовательных S и X, не будут взаимно блокировать друг друга.

Верно ли я рассуждаю?
15 янв 13, 22:32    [13775120]     Ответить | Цитировать Сообщить модератору
 Re: U блокировки  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
Читаем внимательно. Две транзакции одновременно могут получить S блокировку и при попытке конвертации в Х могут получить deadlock. В отличии от "две транзакции не могут одновременно получить U блокировку". Одна из них будет просто ждать.
15 янв 13, 22:42    [13775141]     Ответить | Цитировать Сообщить модератору
 Re: U блокировки  [new]
PM2010
Member

Откуда:
Сообщений: 70
pkarklin, да, я это и имел в виду. :)
15 янв 13, 23:00    [13775199]     Ответить | Цитировать Сообщить модератору
 Re: U блокировки  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
PM2010
да, я это и имел в виду. :)


Из Вашего сообщения не следует, поняли ли Вы суть процитированного Вами же. К сожалению...

Сообщение было отредактировано: 15 янв 13, 23:40
15 янв 13, 23:12    [13775240]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: U блокировки  [new]
PM2010
Member

Откуда:
Сообщений: 70
И всё-таки.

Пусть у нас есть строка, на которой нет блокировок.
Транзакция 1 запрашивает блокировку U, успех.
Транзакция 2 запрашивает блокировку S, успех.
Транзакция 3 запрашивает блокировку U, отказ, ожидание.
Транзакция 2 хочет повысить блокировку S до Х, отказ, ожидание.
Транзакция 1 хочет повысить блокировку U до Х, но транзакция 2 наложила блокировку S, отказ(?), ожидание(?), deadlock(?).
19 фев 14, 11:04    [15587814]     Ответить | Цитировать Сообщить модератору
 Re: U блокировки  [new]
invm
Member

Откуда: Москва
Сообщений: 9833
PM2010
отказ(?), ожидание(?), deadlock(?)
А как по вашему, что будет, если 2 ждет 1, а 1 ждет 2?
19 фев 14, 11:14    [15587927]     Ответить | Цитировать Сообщить модератору
 Re: U блокировки  [new]
PM2010
Member

Откуда:
Сообщений: 70
invm, по-моему будет deadlock.

Тогда поднимается вопрос из первого сообщения
PM2010
Тогда в чем смысл было городить эту [U] блокировку?
19 фев 14, 11:17    [15587952]     Ответить | Цитировать Сообщить модератору
 Re: U блокировки  [new]
invm
Member

Откуда: Москва
Сообщений: 9833
PM2010, U не есть гарантированное средство предотвращать дедлоки.
19 фев 14, 11:25    [15588038]     Ответить | Цитировать Сообщить модератору
 Re: U блокировки  [new]
PM2010
Member

Откуда:
Сообщений: 70
Так это и видно из моего примера. Но ведь U-блокировка преподносится как раз как способ уменьшения взаимных блокировок, в документации приводится пример, когда две транзакции выполняют повышение S=>X. Я же взял тот же пример, но одной транзакции вместо S написал U и получился тот же результат - взаимная блокировка.

Подозреваю, что преимущества U-блокировок проявляются только если в запросах SELECT, за которыми может следовать (а может и не следовать) UPDATE явно указывать UPDLOCK. И вот тогда, если встретились две транзакции с UPDLOCK, то взаимной блокировки не будет. В противном случае будет как в примере.
19 фев 14, 11:37    [15588149]     Ответить | Цитировать Сообщить модератору
 Re: U блокировки  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381
PM2010
invm, по-моему будет deadlock.

Тогда поднимается вопрос из первого сообщения
PM2010
Тогда в чем смысл было городить эту [U] блокировку?


между 1 и 3 deadlock-а не будет зато. и update это достаточно типичный сценарий повышения блокировки от чтения до X, чтобы ввести U. хотя, это и не панацея.
19 фев 14, 11:38    [15588171]     Ответить | Цитировать Сообщить модератору
 Re: U блокировки  [new]
invm
Member

Откуда: Москва
Сообщений: 9833
PM2010
Но ведь U-блокировка преподносится как раз как способ уменьшения взаимных блокировок
Ну так уменьшения, а не безусловного избавления от них.
19 фев 14, 11:52    [15588323]     Ответить | Цитировать Сообщить модератору
 Re: U блокировки  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
PM2010
Так это и видно из моего примера. Но ведь U-блокировка преподносится как раз как способ уменьшения взаимных блокировок ...
С каких пор буквы U и S одиноко пишутся и одинаково читаются?
Да взаимных U блокировок между собой не будет.

Говорится "использование" - означает использование во всём решении а не в конкретном одном запросе.
Если есть хоть один запрос с S -> X, это означает не использование U.

Это как сказать "будьте честными - тогда вас не обманут", а не "если все будут честными, тогда не будет обмана".

В документации ничего не "позиционируется" как вы пишете.

автор
Подозреваю, что преимущества U-блокировок проявляются только если в запросах SELECT, за которыми может следовать (а может и не следовать) UPDATE явно указывать UPDLOCK.
Считаю что сказано неточно и может запутать.
Можно подумать что надо всегда ставить UPDLOCK при чтениях.
И слово "преимущество" тоже для меня странно звучит.

Нужно просто давать скулю заранее всю информацию.
Не должно быть такого "может быть, а может и не быть". Если вы будете делать Один запрос - то выбор U локировка или не U делается автоматически ибо он может понять намерения команды. Но если одну команду размазывают на несколько (что уже плохо), то скуль не может увидеть этого.

Считаю что если нельзя определить будет изменение или нет - плохой подход. Транзакции должны быть минимальными/короткими.

Более того. В данном случае уже минимум 2 команды, следовательно можно нарваться на случай когда в одном случае будет U локировка на 1й ресурс, а во второй сессии на 2й, а затем идёт наоборот - в итоге опять дедлок.

Для одной команды тоже может быть, хотя это не чаще встречается (следует из свойств архитектуры системы).
19 фев 14, 19:46    [15593136]     Ответить | Цитировать Сообщить модератору
 Re: U блокировки  [new]
PM2010
Member

Откуда:
Сообщений: 70
Mnior
С каких пор буквы U и S одиноко пишутся и одинаково читаются?
Не понял, на что Вы пытаетесь намекнуть. Перечитал свои сообщения, вроде нигде не опечатался.

Mnior
В документации ничего не "позиционируется" как вы пишете.
Смотрим первоисточник.
Документация
Чтобы избежать этой потенциальной взаимоблокировки, применяются блокировки обновления (U).
Под "позиционируется" я это предложение и подразумевал.

Mnior
Считаю что если нельзя определить будет изменение или нет - плохой подход.
Пусть у меня есть N приложений, которые берут из таблицы задачки по одной, ставят на обработку и помечают, что задача в работе, чтобы другие приложения ее не забрали себе. ID задачи я заранее не знаю.
...
SELECT @id = TOP(1) [id] FROM [Task] WITH (UPDLOCK, ROWLOCK) WHERE ([BeingProcessed] = 0)
IF (@id IS NOT NULL) THEN
    UPDATE [Task] SET [BeingProcessed] = 1 WHERE ([id] = @id)
...
Что я сделал плохого? Заранее известно, что изменение будет, но где?
20 фев 14, 23:12    [15602103]     Ответить | Цитировать Сообщить модератору
 Re: U блокировки  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
PM2010
Смотрим первоисточник.
http://technet.microsoft.com/ru-ru/library/ms175519
Блокировка с намерением выполняет две функции:
* предотвращает изменение ресурса более высокого уровня другими транзакциям таким образом, что это сделает недействительной блокировку более низкого уровня;
* повышает эффективность компонента Database Engine при распознавании конфликтов блокировок на более высоком уровне гранулярности.
Не вижу никаких гарантий.
http://technet.microsoft.com/ru-ru/library/ms175519
Чтобы избежать этой {см. контекст} потенциальной взаимоблокировки, применяются блокировки обновления (U). Блокировку обновления (U) может устанавливать для ресурса одновременно только одна транзакция. Если транзакция изменяет ресурс, то блокировка обновления (U) преобразуется в монопольную (X) блокировку.
Интерпретируется статья довольно однозначно.
Не говорится про другие случаи.
Говорится что применяются в этом решении, а не применяется в этом одном месте кода.
Говорится что применяются для предотвращения дедлока, а не для защиты куска кода от проблем. Дедлок это не проблема куска кода, это проблема использования ресурса всеми процессами.
PM2010
Что я сделал плохого? Заранее известно, что изменение будет, но где?
В том-то идело. У вас заранее известно что ресурс будет не просто считан, но и заблокирован.
А я говорю про случай, когда ресурс считывается, но при этом не известно будет ли он блокироваться ибо код почему-то безолаберно используется в несколько разных по смыслу ТЗ. Явно неправильный подход.

Заранее известно не где (в коде), а в постановке задачи. Поэтому считывающий ресурс обязан сразу налагать локировку U вместо S.

Ваш пример заведомо неправильно решён, он не подходит для примера.
У вас всё делается одной командой.
UPDATE	Top(1) T
SET	BeingProcessed	= 1
,	@ID		= T.ID
FROM	dbo.[Task]	WITH (ReadPast) AS T
WHERE	T.BeingProcessed= 0
Хотя внутрях там будет считывание как U и затем X.
Это вообще редкость когда надо сначала отдельно считать, а потом изменять.
Но понимать это надо. К примеру с командой MERGE есть подстава.
ReadPast - для конкурентности процессов, к теме отношения не имеет.

Вообще "считывать, а затем менять" применяется в совсем других случаях, когда для обновления необходимо сделать предварительные расчёты. Но вообще лучше сразу сменить состояние у объекта, словно всё уже сделано.

Бич современных кодеров в том, что они излагают в коде ход своих мыслей, вместо того чтобы написать решение. Они думают:
аффтар
- Так, сначала мне надо получить вот эти данные (трум трум по клаве), посчитали, а вот надо ещё эти данные (трум трум, ещё пару команд), а теперь вот так (трум), всё, надо записать (трум, трум ещё пару команд), и коммит (трум).
Они даже этого не осознают.
А всё потому что в школах учат императивизму и прививают его с детства.
И это во всём, к примеру вместо понимания математики, людей учат алгоритмам вывода по правилам. Ужас нах. Роботы. Тупые роботизированные лысые обезьяны. Ипучий каменный век. Да простят меня благородные доны за мой французкий.

Можно практически неучем пойти в самом МФТИ на семинар, посмотреть алгоритм взятия очередного финдеперсного типа диффура, вызваться профессором к доске и "решить" стеклянными глазами месиво символов с полной пустотой в голове и быть похваленным этим профЭссором за отличные "знания".
И упасть в осадок от этого эксперимента - это самый худший демотиватор в жизни.

IF (@id IS NOT NULL) THEN
1. Это форум по MS SQL.
2. Люди часто забывают про @@RowCount
21 фев 14, 05:31    [15602880]     Ответить | Цитировать Сообщить модератору
 Re: U блокировки  [new]
PM2010
Member

Откуда:
Сообщений: 70
Mnior, спасибо, мне всё понятно, кроме заведомости неправильного решения. Как понять, что решение неправильное еще до его просмотра (т.е. заведомо)?
Mnior
binome
IF (@id IS NOT NULL) THEN
1. Это форум по MS SQL.
IS NOT NULL в MS SQL работает. А THEN простите, регулярно сталкиваюсь с VBA, поэтому порой путаюсь.
21 фев 14, 12:54    [15604445]     Ответить | Цитировать Сообщить модератору
 Re: U блокировки  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
PM2010
Mnior
Ваш пример заведомо неправильно решён, он не подходит для примера.
мне всё понятно, кроме заведомости неправильного решения. Как понять, что решение неправильное еще до его просмотра (т.е. заведомо)?
Да, согласен, это слово было лишним.
PM2010
Mnior
1. Это форум по MS SQL.
2. Люди часто забывают про @@RowCount
IS NOT NULL в MS SQL работает. А THEN простите, регулярно сталкиваюсь с VBA, поэтому порой путаюсь.
1й пункт был к THEN, 2й к "@id IS NOT NULL", не как что-то неправильное, а как "чаще/надёжнее/альтернатива".
21 фев 14, 23:21    [15608848]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить