Normally I very much agree with the things
Jeff Atwood has to say. In the case of
this post, however, I must take issue. What begins with a decent intro into the concept of deadlocks eventually ends with Jeff deciding to use the NOLOCK
table hint to allow dirty reads of a table that had been locked by an update statement. He concludes with a complaint that Microsoft seems to think that
Stack Overflow is a banking institution and therefore worthy of data integrity instead of the mere programmers blog/wiki/link exchange that it really is.
Jeff wildly misses the mark with his conclusion, in my opinion.
Not only is NOLOCK deprecated, Jeff seems to believe that data integrity is something one can safely do without "in certain scenarios". He is wrong. Every database not only deserves but
requires data integrity.
Of the dozens of posts that replied to Jeff's article, a few diagnosed the real issue (long updating transactions) but only one (at least as of the time of this post) supplied the correct solution (in my opinion) to Jeff's problem. The poster's name was Filip and
his blog is worth adding to your feed reader. The solution Filip pointed out is simple: Lock all your resources *before* you update them and put a waiting lock on them (HOLDLOCK) so that queries that want to use the resource wait until the update is done rather than dying petulantly.
UPDATE:
Sam Saffron (also another great addition to your feed reader) has
posted an excellent rebuttal of Jeff's post explaining how and why deadlocks occur when selecting against an update and how to deal with them. Read it and remember it.
Ok, imagine the following situation:
You are a developer and you want to keep up with the latest technology, so you update Visual Studio 2008 with
Service Pack 1, installing .NET 3.5 Service Pack 1 as part of the update. You then proceed to continue with your ASP.NET application, building a nice neat AJAXy application. Everything works fine on your box, it's awesome, the in-your-cube demos go great, everybody's happy. So you build and deploy your new hotness then sit back and wait for the pats on the back.
The pats never come. Instead, you get reports of exceptions being thrown by the application every request. Something has gone horribly wrong. It's always the same exception:
Could not load type 'System.Web.UI.ScriptReferenceBase' from assembly
'System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35'.
You are stymied. You've never heard of the class; you certainly don't use it in your code. You use
ScriptReference, of course; who doesn't? But what's
ScriptReferenceBase? Going to the documentation for ScriptReferenceBase, you learn that it is the parent class of ScriptReference and
CompositeScriptReference. What? No it isn't! The documentation for ScriptReference clearly indicates that it's parent is
System.Object! What's going on here?
Then you notice the Version Information for ScriptReferenceBase: "Supported in: 3.5 SP1". It's a new class for Service Pack 1. It doesn't exist in .NET 3.5 and the documentation for ScriptReference is clearly stale.
Following a hunch, you double-check your server... yep. Due to red tape, SP1 hasn't been installed on the server. It turns out that when you compiled your code with the SP1 ScriptReference, you built a reference to ScriptReferenceBase and that class just isn't on the server. The solution is simple: install SP1 on the server.
Except you can't upgrade to SP1! Internal circumstances (i.e. no time for regression testing) means no upgrade. So no biggie; you return to Visual Studio 2008 and decide to target .NET 3.5 rather than .NET 3.5 SP1.
Except, surprise! You can't. Visual Studio will target .NET 3.0 and 2.0, but it won't let you differentiate between .NET 3.5 and .NET 3.5 SP1. OUCH.
So what do you do? At this point, your options are limited. The best option is to install SP1 on the server, but sometimes internal pressures won't allow that. Other options include uninstalling SP1 from your box and recompiling -- good luck with that one! -- and finding an unadulterated version of VS 2008 somewhere (a co-worker's box, maybe a virtual machine) and compiling there.
So why am I writing about this hypothetical situation? Because it happened to me, of course! I learned an important lesson. Maybe you can too.