I use SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
in the majority of my general SQL queries, mainly because this was drilled in to me when originally learning the language.
From my understanding, this isolation level acts the same way that WITH (NO LOCK)
however I only ever tend to use SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
.
- Is there ever a time that I should be using
WITH (NO LOCK)
overSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
. - Does
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
stop other users from being locked out of the tables that I am reading? - If
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
is used to stop locks, but I am only reading data, what is the point in using it? Is it only system intensive queries that would generate locks? Is it worth using it when running queries that would return in say, 5-10 seconds? - I have been told not to use
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
when reading data that would be used in updates, presumably to avoid updating dirty data. Would this be the only reason? - With the type of database that I am working on, there is a production and testing environment. We will very rarely be querying the production environment but when I need to, I will generally be using
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
in my query. I understand that dirty reads are possible with this. Aside from receiving data back that may not end up being committed to the database (and therefore throw my results out) what other types of 'dirty reads' could be possible?
Sorry for the mass questions.
Best Answer
It is terrible, that you learned it that way (sorry!).
READ UNCOMMITTED
let's you read every row, yes. Even those who are currently used in anINSERT
,UPDATE
,DELETE
operation. This is very useful if you need to take a quick look at some Data or in mission criticalSELECT
-Statements where a block would be very harmful.In fact, you risk your integrity. It may occur that you read a row, which is currently used to be deleted or in a change. It can also appear that you read a wrong value. This may be really uncommon, but it can happen. What do I mean with that? Well, think of a row which is very broad (it has many columns with many long
nvarchar
-columns). An update occur on this row and sets new values. In rare cases it can happen to you, that you read only a half row. Another thing can happen for example, if a user changes his login values. He changes his mail + password. The mail is already set, but the password isn't. This way you have a inconsistent state.I would suggest to forget about
READ UNCOMMITTED
. Just use it where it's really needed.Another alternative for you can be to enable the
READ_COMMITTED_SNAPSHOT
database option - therefor you can useREAD COMMITTED SNAPSHOT
due to the enabled row versioning in your tempdb. This way you just read another (older) version of a row. This won't block your Queries. But it may occur that you read an old value too, but an consistent old value.Another idea can be
WITH(READPAST)
instead ofWITH(NOLOCK)
. You will read the old state of the table (a bit like in theSNAPSHOT ISOLATION
), but you'll skip all currently locked rows instead.