开发者

Stored procedure SQL Server 2005 transaction deadlock problem

I have a problem while running sql stored procedure (MSSQL 2005). Here is the code of it:

CREATE PROCEDURE [GetItemColors]
    @FetchCount int
AS
BEGIN
SELECT 
    TOP (@FetchCount) item.Id as ItemId, item.Published as Published, attributeValue.String as Color
    FROM tblItem item, tblAttribute attributeValue, tblAttributeDefinition attributeDef
    WHERE 
        item.Id = attributeValue.fkItemId 
        AND item.Deleted = 0
        AND item.PendingPublish = 0 
        AND attributeValue.fkAttributeDefinitionId = attributeDef.Id
        AND attributeDef.[Name] = 'Color'
    ORDER BY item.Published DESC
END;

Some times the execution of the procedure ends with exception:

SqlException: Transaction (Process ID 66) was deadlocked on lock | communication buffer resources with another process and has been chosen as the dea开发者_运维技巧dlock victim. Rerun the transaction.

Does anyone know how to rewrite the procedure to avoid the exception?

Is there anyway of 'pre-locking' tables within the stored procedure invocation so other code can't interrupt the execution?

Thanks in advance for you help!


edit 1: Estimated execution plan attached

Stored procedure SQL Server 2005 transaction deadlock problem


edit 2: I can't get Deadlock Graph as the exception happens couple times per day in the live environment only. I'm not allowed to run profiler in live environment. I didn't manage to reproduce the deadlock in development environment.


edit 3: I didn't managed to get the deadlock winner.


  1. post the deadlock info. See How to: Save Deadlock Graphs.
  2. post the statement this procedure deadlocks with (ie. the deadlock winner)
  3. post the exact schema of your tables involved, including all the indexes, clustered and non-clustered

You execution plan has no less than 3 clustered index scans. With a picture of the plan instead of the actual plan one cannot say what are the actual properties of the operators, but those lines look quite thick (indicating large results) and they are behind parallelism operators. All these point toward a bad indexing strategy that causes table scans. Such large scans are guaranteed to conflict with any update. When the conflict results in a deadlock (which often happens due to index update order) then this query, as a read-only operation, will always be chosen ads a victim.

One solution is to properly index your database as to no longer have those expensive table scans. Besides overall performance benefit, it will also reduce the probability of deadlock conflict.

If deadlock persist, then the answer would be very specific depending on the actual deadlock situation.

As for a magic 'pre-lock' strategy, you can take a sledgehammer and decorate your query with or TABLOCK or even TABLOCKX hints, but the performance will go down the drain in no time. The proper solution is to address the deadlock, not to force serialization.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜