Occasionally, I have the following error for a stored procedure which is only a Select query: Transaction (Process ID 91) was deadlocked on lock
My initial understanding was that a select query won't lock a table, or won't cause a deadlock even if the table it tries to query is being updated/locked by another process, but it seems that a select query can cause deadlocks as well.
If I set the isolation level to read uncommitted for the query, will that solve the problem?
SELECT queries take shared locks on the rows they analyze. Shared locks may conflict exclusive locks from update/delete/insert statements. Two SELECT statements are not going to deadlock, but a SELECT can deadlock with an UPDATE.
In a highly concurrent application it could (theoretically) happen that data you've read in the first select is modified before the other selects are executed. If that is a situation that could occur in your application you should use a transaction to wrap your selects.
The only way to resolve a SQL Server deadlock is to terminate one of the processes and free up the locked resource so the process can complete. This occurs automatically when SQL Server detects a deadlock and kills off one of the competing processes (i.e., the victim).
To trace deadlock events, add the Deadlock graph event class to a trace. This event class populates the TextData data column in the trace with XML data about the process and objects that are involved in the deadlock. SQL Server Profiler can extract the XML document to a deadlock XML (.
My init understanding is that a Select query won't lock a table, or won't cause a deadlock
This understanding is wrong. SELECT queries take shared locks on the rows they analyze. Shared locks may conflict exclusive locks from update/delete/insert statements. Two SELECT statements are not going to deadlock, but a SELECT can deadlock with an UPDATE. When such deadlock occurs, the SELECT is usually the victim as it did not perform any update so is always going to loose the draw.
As with any deadlock, you need to post the exact schema of the tables involved, the exact T-SQL statements and the deadlock graph. See How to: Save Deadlock Graphs (SQL Server Profiler). With this information you can receive guidance how to fix the deadlock.
Like Remus says, you are getting the deadlocks because SELECT and UPDATE (or other) operations deadlocking each other, not SELECT vs SELECT. You will have to look at all your queries touching that table and create proper covering indexes for those queries and that will solve your problems. Good covering indexes is the preferred solution rather than using WITH (NOLOCK) table hints.
See the following link for a good tutorial on how to create covering indexes and how it affects deadlocks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With