Не используйте with nolock


11 0

У нас сейчас на работе очень много используют nolock опции при выполнении SELECT запросов. Эту опцию можно использовать только в самых крайних случаях и настоятельно рекомендую избежать её использование. 

Когда выполняется долгий SELECT запрос, то база данных может блокировать данные, что сильно замедляет производительность сервера. Если какой-то зарос выполняется слишком часто, но с блокировкой, то на сервере может выстраиваться очередь на выполнение запроса и пользователь будет видеть задержки загрузки данных, пока его запрос ожидает в очереди, или даже таймауты. Чтобы не было ни того ни другого, начинают использовать опцию NOLOCK. Это выглядит примерно так:

SELECT * FROM Employee WITH (NOLOCK)

Даже если Employee таблица сейчас заблокирована кем-то, сервер все равно выполнит этот запрос и вернёт данные. 

Но тут есть серьёзная проблема, сервер вернёт данные, даже если их сейчас кто-то обновляет и даже если они сейчас не закомичены (ужас, какое слово, но русского аналога в голову н пришло, слишком много говорю на английском). То если если кто-то изменил имя клиента, а мы читаем данные, то мы увидим изменённое значение. Если измените откатят с помощью rallback, то получиться, что прочитанное нами значение неверно. 

В финансовых и около финансовых приложениях старайтесь не использовать NOLOCK. Случаи, когда данные откатываются происходят иногда и если какой-то запрос почитал неподтвержденным данные, то это может привести к нарушению целостности информации. 

Опция NOLOCK действительно создаёт видимость увеличения производительности. Но это только видимость. Проблем от её использования на много больше, если потерять целостность данных. 

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


Понравилось? Кликни Лайк, чтобы я знал, какой контент более интересен читателям. Заметку пока еще никто не лайкал и ты можешь быть первым


Комментарии

Андрей

13 Aпреля 2016

не закомичены  -  не подтверждены   ?


Ololo

13 Aпреля 2016

Нормальные люди уже давно включают версинность вместо блокировок. Наверное, пользователи SQL Server самые отсталые из всех потому, что по дефолту эти опции выключены, хотя такая возможность появилась ещё в 2005й версии, в отличии от всех других СУБД (Firebird, Oracle, PostgreSQL, MySQL), а людям не хватает ума почитать документации что в мире есть не только блокировки.


Михаил Фленов

13 Aпреля 2016

Версионность не бесплатна. У нее тоже есть недостатки, почитай о них, прежде чем включать ее. Один из них - на update и delete создаются версии строк в tempdb и это увеличивает на нее нагрузку. Если бы у этого уровня чтения были бы только преимущества, его бы использовали по умолчанию и MS всех насильно перевела бы на него.


Илья

13 Aпреля 2016

Ololo, Oracle в твоем списке явно лишний. Это СУБД-версионник.


Ololo

13 Aпреля 2016

Все современные СУБД кроме SQL Server используют многоверсионность по-умолчанию, неужто все тупые, а одни Microsoft умней всех? Думаю, они не меняют дефолтное поведение чтобы привыкших к блокировкам не кидать в ступор, что всё работает хорошо даже без лишних действий. Более того, слышал что SQL Server в Azure использует многоверсионность по-умолчанию. По блокировкам вечно слышишь вот такие проблемы что всё тупит, лочится, часто бывают дедлоки. Был я на одном проекте с базой около 400Гб там был блокировочный режим и некоторые запросы выдавали дедлок при множесте пользователей, конечно скорее всего те запросы были кривые, но тем немнее простой перевод на версионность решил проблемы с дедлоками, потом спецы по базам тестировали на проде пришли к выводу что многоверсионность повысила общую производительность и убрала дедлоки. Так что не вижу никаких причин использовать этот устаравший режим явно минусов у него больше.


Михаил Фленов

13 Aпреля 2016

Oracle изначально был версионником и не сравнивайте его архитектуру с MS SQL Server. Версионность - один из возможных способов решения проблемы блокировок.


Lt

13 Aпреля 2016

С блокировками SQL Server работает быстрее и расходует меньше ресурсов, поэтому по умолчанию до сих пор используется он. Когда программисты не умеют оптимизировать свой код, то им проще использовать nolock или перейти на версионность, потому что при большем расходе ресурсов, она работает с SQL Server.


Илья

14 Aпреля 2016

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


Михаил Фленов

14 Aпреля 2016

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


Ololo

14 Aпреля 2016

Ну а чё моё сообщение с профуми о разных СУБД не публикуешь?


Михаил Фленов

14 Aпреля 2016

Ели в сообщении были линки, то оно скорей всего не сохранилось. Я не знаю, что такое "профуми", я так понимаю, ты хотел что-то доказать про разные базы данных. Хочешь использовать версионность, используй даже на SQL Server, в ней ничего плохого нет. Хочешь доказать, что MS не правы, что по умолчанию нет версионности, то надо написать им, а не мне.


Добавить Комментарий

Еще что-нибудь

Хотите найти еще что-то интересное почитать? Можно попробовать отфильтровать заметки на блоге по категориям.

О блоге

Программист, автор нескольких книг серии глазами хакера и просто блогер. Интересуюсь безопасностью, хотя хакером себя не считаю

Обратная связь

Без проблем вступаю в неразборчивые разговоры по e-mail. Стараюсь отвечать на письма всех читателей вне зависимости от страны проживания, вероисповедания, на русском или английском языке.

Пишите мне