Как предотвратить / устранить тупики в MSSQL?

Мой Windows-сервис, написанный на C#, иногда (несколько раз в неделю) регистрирует сообщение примерно так:

getClientData: Транзакция (идентификатор процесса ###) была заблокирована для ресурсов блокировки с другим процессом и была выбрана в качестве жертвы тупика. Перезапустите транзакцию.

getClientData моя собственная функция C#, которая просто вызывает хранимую процедуру. Хранимая процедура является реализацией очереди приоритет + ожидание в mssql. Я получил идею отсюда.

Я только что нашел это объяснение того, как тупик может произойти без транзакций в простом запросе выбора (+ дополнительные вещи, происходящие в фоновом режиме). Теперь эти взаимоблокировки не так уж и важны, потому что это не приводит к сбою моего сервиса (я просто повторяю запросы), но я хотел бы знать, возможно ли избавиться от этих взаимоблокировок.

Ох, и данные вставляются в [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 ответов

Другие вопросы по тегам