Can adding a primary key identity column solve deadlock issues?

吃可爱长大的小学妹 提交于 2019-12-01 14:57:26

问题


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:

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).


回答1:


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.




回答2:


Recently I have seen this post, according to above information i hope this post will help you,

http://databaseusergroup.blogspot.com/2013/10/deadlocked-on-sql-server.html



来源:https://stackoverflow.com/questions/10737324/can-adding-a-primary-key-identity-column-solve-deadlock-issues

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!