如何防止/解决MSSQL中的死锁?

时间:2015-06-02 12:47:09

标签: sql-server database-deadlocks

我的Windows服务,偶尔用C#编写(每周几次)记录这样的消息:

  

getClientData:事务(进程ID ###)在锁定时死锁   资源与另一个进程并被选为死锁   受害者。重新运行该交易。

getClientData是我自己的C#函数,只调用存储过程。存储过程是mssql中优先级+挂起队列的实现。我从here得到了这个想法。

我刚刚找到了this解释如何在没有简单选择查询中的事务的情况下发生死锁(+后台发生的其他事情)。现在,这些死锁并不是那么重要,因为这不会导致我的服务崩溃(我只是重试查询),但我想知道是否可以摆脱这些死锁。

哦,并且,数据从几个不同的来源一次一行地插入到[dbo].[tbl_client_data]表中(但它们都只是简单的一行插入)。

存储过程看起来非常像这样(有更多数据列,但这似乎与我无关):

CREATE PROCEDURE [dbo].[sp_get_client_data]
    @client_id [int],
    @limit [int] = 0
AS
BEGIN
    IF(@limit < 0) SET @limit = 0;

    DECLARE @data TABLE
    (
        [id] [int],
        [data] [varchar](max),
        [client_id] [int],
        [ts] [datetime],
        [priority] [tinyint]
    );

    IF(@limit > 0)
    BEGIN
        DELETE TOP(@limit)
          FROM [dbo].[tbl_client_data]
        OUTPUT DELETED.[id]
              ,DELETED.[data]
              ,DELETED.[client_id]
              ,DELETED.[ts]
              ,DELETED.[priority]
          INTO @data
         WHERE [id] IN (SELECT TOP(@limit) [id]
                          FROM [dbo].[tbl_client_data] with(nolock)
                         WHERE ([ts] IS NULL OR [ts] <= GETDATE())
                           AND [client_id] = @client_id
                        ORDER BY [priority], [ts]);
    END

    SELECT *
      FROM @data
    ORDER BY [priority], [ts];
END

所以我的问题是 - 有没有办法摆脱这些偶然的(非常罕见的)死锁,或者我应该忽略它们,只是按照我的知识重试查询?

0 个答案:

没有答案