Разница в блокировке базы данных SQL между SELECT и UPDATE - PullRequest
0 голосов
/ 17 мая 2018

Я переписываю старую хранимую процедуру, которая вызывается BizTalk.Теперь у этого есть потенциал, чтобы пропустить 50-60 сообщений сразу.У меня иногда возникает проблема с блокировкой базы данных, когда все они пытаются обновить сразу.Я могу вносить изменения только в SQL (не BizTalk), и я пытаюсь найти лучший способ запустить мой SP.Имея это в виду, я сделал большую часть оператора, чтобы определить, нужно ли ОБНОВЛЕНИЕ, используя инструкцию SELECT.

Какой у меня вопрос - в чем разница между блокировкой между оператором UPDATE и SELECT с NOLOCK против него?

Надеюсь, это имеет смысл - Спасибо.

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Вы используете nolock, когда хотите прочитать неподтвержденные данные и хотите избежать ввода каких-либо shared lock данных, чтобы другие транзакции могли взять exclusive блокировку для обновления / удаления.

Вам следуетне используйте nolock с оператором update, это действительно плохая идея, MS говорит, что nolock игнорируется для цели update/insert оператора.

Поддержка использования READUNCOMMITTEDи подсказки NOLOCK в предложении FROM, которые применяются к целевой таблице оператора UPDATE или DELETE, будут удалены в будущей версии SQL Server.Избегайте использования этих советов в этом контексте в новых разработках и планируйте модифицировать приложения, которые в настоящее время их используют. Источник

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

Чтобы решить эту проблему, вы можете выбрать записи, используя UPDLOCK, как указано ниже

DECLARE @IdToUpdate INT
SELECT @IdToUpdate =ID FROM [Your_Table] WITH (UPDLOCK) WHERE A=B

UPDATE [Your_Table]
SET X=Y
WHERE ID=@IdToUpdate

Это заберет необходимую блокировку обновления для записи заранее и остановит другие сеансы для получения.любая блокировка (общая / исключительная) для записи и предотвращение любых тупиков.

0 голосов
/ 17 мая 2018

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

Таким образом, при использовании NOLOCK вы возвращаете все строки назад, но есть вероятность чтения незафиксированных (грязных) данных.А при использовании READPAST вы получаете только подтвержденные данные, поэтому есть вероятность, что вы не получите те записи, которые в настоящее время обрабатываются и не фиксируются.

Для лучшего понимания перейдите по ссылке ниже.

https://www.mssqltips.com/sqlservertip/2470/understanding-the-sql-server-nolock-hint/ https://www.mssqltips.com/sqlservertip/4468/compare-sql-server-nolock-and-readpast-table-hints/ https://social.technet.microsoft.com/wiki/contents/articles/19112.understanding-nolock-query-hint.aspx

...