Library tutorials & articles
SQL Server Locks
- Introduction
- Lock Contention Described
- Lock Contention Solved
- NOLOCK and ROWLOCK
- Conclusion
NOLOCK and ROWLOCK
In the last section we discussed what row-locking was, why it was done, and its impact on database performance. In this part we'll examine two query-level hints you can provide SQL Server with to specify how you want SQL to handle locking!
NOLOCK
Using NOLOCK politely asks SQL Server to ignore locks and read directly
from the tables. This means you completely circumvent the lock system, which
is a major performance and scalability improvement. However, you also completely
circumvent the lock system, which means your code is living dangerously. You
might read the not-necessarily-valid uncommitted modifications of a running transaction.
This is a calculated risk.
For financial code and denormalized aggregates (those little counters of related data that you stash away and try desperately to keep accurate), you should play it safe and not use this technique. But I think you'll find that for better than 90% of your application, it would not be that big of a deal if a user (or even intermediate code) saw an uncommitted modification. In fact, you'll probably find that most of your data never or only very rarely changes, in which case the overhead of locking the data is almost always completely wasted.
For example, if I want to count all users that joined Streamload.com between June 1 and August 31 of Y2K, there's no reason for me to lock anything: that number was cast in stone the moment September 1, 2000 rolled around. Another example is the file listings you see on Streamload.com: it doesn't much matter if you don't see the exact perfect data, since either you don't own the data and it doesn't much matter what you see, or you do own the data and you know perfectly well whether you just modified the data or not and whether new files have finished uploading.
Just don't use this type of data as the basis for modifications to the database, and don't use it when it's really important that the user not see the wrong thing (an account statement or balance, for instance).
ROWLOCK
Using ROWLOCK politely asks SQL Server to only use row-level locks.
You can use this in SELECT, UPDATE, and DELETE
statements, but I only use it in UPDATE and DELETE
statements. You'd think that an UPDATE in which you specify the
primary key would always cause a row lock, but when SQL Server gets a batch with
a bunch of these, and some of them happen to be in the same page (depending on
this situation, this can be quite likely, e.g. updating all files in a folder,
files which were created at pretty much the same time), you'll see page locks,
and bad things will happen. And if you don't specify a primary key for an UPDATE
or DELETE, there's no reason the database wouldn't assume that a
lot won't be affected, so it probably goes right to page locks, and bad things
happen.
By specifically requesting row-level locks, these problems are avoided. However, be aware that if you are wrong and lots of rows are affected, either the database will take the initiative and escalate to page locks, or you'll have a whole army of row locks filling your server's memory and bogging down processing. One thing to be particularly aware of is the "Management/Current Activity" folder with Enterprise Manager. It takes a long time to load information about a lot of locks. The information is valuable, and this technique is very helpful, but don't be surprised if you see hundreds of locks in the "Locks/Processes" folder after employing this technique. Just be glad you don't have lock timeouts or deadlocks.
Notes:
I get the sense that SQL Server honors NOLOCK requests religiously,
but is more discretional with ROWLOCK requests. You can only use
NOLOCK in SELECT statements. This includes inner queries,
and the SELECT clause of the INSERT statement. You
can and should use NOLOCK in joins:
SELECT COUNT(Users.UserID)
|
Related articles
Related discussion
-
High-Performance .NET Application Development & Architecture
by Manjot Bawa (0 replies)
-
Permutations and combinations of multiple return codes
by actuszeus (1 replies)
-
help needed on tree level sql?
by kareen (0 replies)
-
dtPicker date format query
by konikula (1 replies)
-
VB Function for Sending SMS
by kisna (8 replies)
Related podcasts
-
Stack Overflow: Podcast #28
This is the twenty-eighth episode of the StackOverflow podcast, where Joel and Jeff discuss Windows Azure, SQL Server 2008 full text search, Bayesian filtering, porn detection, and project management — among other things. Jeff met the inestimable Joey DeVilla aka Accordion Guy...
Events coming up
-
Jul
7
Midlands PASS Chapter July Meeting
Columbia, United States
Midlands PASS welcomes SQL Server MVP John Welch. John will be giving a talk on Getting Started with Analysis Services 2008. We meet in the Training Concepts facility (Suite 502).
To get more information about Isolation levels in SQL Server including Locks and its impact on database in detail with examples, refer the below link: http://www.sqllion.com/2009/07/transaction-isolation-levels-in-sql-server/
!--removed tag-->I've implemented the [WITH (NOLOCK)] hint and it's been a reasonable success. The only additional note of caution I would add is that we have one table that is occasionally updated (batch inserts).
The problem is that the data is inserted and then the index is updated. If the index is read after the data has been updated but before the index is updated then this can cause the following error:
Number = -2147217900, Description = Could not continue scan with NOLOCK due to data movement., Source = Microsoft OLE DB Provider for SQL Server, SQLState = 42000, Native Error = 601.
Great.
This little hint with those little word (nolock) saved my life - and the life of our application. (http://www.gpsoverip.de)
Thank you VERY much ...
You say (with regard to locking): "For financial code and denormalized aggregates (those little counters of related data that you stash away and try desperately to keep accurate), you should play it safe and not use this technique. But I think you'll find that for better than 90% of your application, it would not be that big of a deal if a user (or even intermediate code) saw an uncommitted modification"
What do you mean? If data is being interrogated, then the returned result set MUST be consistent (ACID).
Seeing uncommitted code is a no-no, whether Financial, denormalized or whatever.
Please contribute your suggestion in relation with various issues related with log file management in SQL server. Such as
1. Methods to Shrinking the log file.
2. Recover the database form Log file
3. Recovery mode etc
This thread is for discussions of SQL Server Locks.