Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can adding a primary key identity column solve deadlock issues?

I have a table in SQL server that is CRUD-ed concurrently by a stored procedure running simultaneously in different sessions:

|----------------|---------|
| <some columns> | JobGUID |
|----------------|---------|

The procedure works as follows:

  1. Generate a GUID.
  2. Insert some records into the shared table described above, marking them with the GUID from step 1.
  3. Perform a few updates on all records from step 2.
  4. Select the records from step 3 as SP output.

Every select / insert / update / delete statement in the stored procedure has a WHERE JobGUID = @jobGUID clause, so the procedure works only with the records it has inserted on step 2. However, sometimes when the same stored procedure runs in parallel in different connections, deadlocks occur on the shared table. Here is the deadlock graph from SQL Server Profiler:

SQL Server Profiler Deadlock Graph

Lock escalations do not occur. I tried adding (UPDLOCK, ROWLOCK) locking hints to all DML statements and/or wrapping the body of the procedure in a transaction and using different isolation levels, but it did not help. Still the same RID lock on the shared table.

After that I've discovered that the shared table did not have a primary key/identity column. And once I added it, deadlocks seem to have disappeared:

alter table <SharedTable> add ID int not null identity(1, 1) primary key clustered

When I remove the primary key column, the deadlocks are back. When I add it back, I cannot reproduce the deadlock anymore.

So, the question is, is a primary key identity column really able to resolve deadlocks or is it just a coincidence?

Update: as @Catcall suggests, I've tried creating a natural clustered primary key on the existing columns (without adding an identity column), but still caught the same deadlock (of course, this time it was a key lock instead of RID lock).

like image 568
Yuriy Guts Avatar asked May 24 '12 12:05

Yuriy Guts


People also ask

How can deadlocks be resolved?

Deadlock frequency can sometimes be reduced by ensuring that all applications access their common data in the same order - meaning, for example, that they access (and therefore lock) rows in Table A, followed by Table B, followed by Table C, and so on.

Can identity column be a primary key?

In many cases an identity column is used as a primary key; however, this is not always the case. It is a common misconception that an identity column will enforce uniqueness; however, this is not the case. If you want to enforce uniqueness on the column you must include the appropriate constraint too.

How can avoid deadlock in SQL?

Useful ways to avoid and minimize SQL Server deadlocksTry to keep transactions short; this will avoid holding locks in a transaction for a long period of time. Access objects in a similar logical manner in multiple transactions. Create a covering index to reduce the possibility of a deadlock.


1 Answers

The best resource (still) for deadlock resolution is here: http://blogs.msdn.com/b/bartd/archive/2006/09/09/deadlock-troubleshooting_2c00_-part-1.aspx.

Pt #4 says:

Run the queries involved in the deadlock through Database Tuning Advisor. Plop the query in a Management Studio query window, change db context to the correct database, right-click the query text and select “Analyze Query in DTA”. Don’t skip this step; more than half of the deadlock issues we see are resolved simply by adding an appropriate index so that one of the queries runs more quickly and with a smaller lock footprint. If DTA recommends indexes (it'll say “Estimated Improvement: %”), create them and monitor to see if the deadlock persists. You can select “Apply Recommendations” from the Action drop-down menu to create the index immediately, or save the CREATE INDEX commands as a script to create them during a maintenance window. Be sure to tune each of the queries separately.

I know this doesn't "answer" the question to why necessarily, but it does show that adding indexes can change the execution in ways to make either the lock footprint smaller or execution time faster which can significantly reduce the chances of a deadlock.

like image 165
Kelly Summerlin Avatar answered Oct 19 '22 07:10

Kelly Summerlin