Нужна помощь с проблемой тупика SQL Server

Нужна помощь в решении этой проблемы взаимоблокировки... У меня есть сохраненный процесс, который довольно часто вызывается из нескольких процессов, но из небольшой таблицы (количество строк меньше тысячи)... Время от времени я получить тупик на процесс.
Цель Proc - вернуть следующие "подходящие для обработки" строки. Очень важно не возвращать одну и ту же строку двум одновременным вызовам процедуры.... (эта часть работает нормально)... но я не могу понять, почему иногда возникает тупик.

Это база данных SQL Azure

Ценим помощь

CREATE PROCEDURE [dbo].[getScheduledAccounts_Monitor]
    -- Add the parameters for the stored procedure here
    @count int,
    @timeout int = 1200,
    @forcedAccountId uniqueidentifier = NULL
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

    DECLARE @batchId uniqueidentifier
    SELECT @batchId = NEWID()

    BEGIN TRAN

    -- Update rows
    UPDATE Schedule 
    WITH (ROWLOCK)
    SET 
        LastBatchId = @batchId, 
        LastStartedProcessingId = NEWID(), 
        LastStartedProcessingTime = GETUTCDATE(),
        LastCompletedProcessingId = ISNULL(LastCompletedProcessingId, NEWID()),
        LastCompletedProcessingTime = ISNULL(LastCompletedProcessingTime, GETUTCDATE())
    WHERE 
        ActivityType = 'Monitor' AND 
        IsActive = 1 AND
        AccountId IN (
            SELECT TOP (@count) AccountId 
            FROM Schedule 
            WHERE 
                (LastStartedProcessingId = LastCompletedProcessingId OR LastCompletedProcessingId IS NULL OR DATEDIFF(SECOND, LastStartedProcessingTime, GETUTCDATE()) > @timeout) AND 
                IsActive = 1 AND ActivityType = 'Monitor' AND
                (LastStartedProcessingTime IS NULL OR DATEDIFF(SECOND, LastStartedProcessingTime, GETUTCDATE()) > Frequency)
            ORDER BY (DATEDIFF(SECOND, LastStartedProcessingTime, GETUTCDATE()) - Frequency) DESC
        ) AND
        AccountId = ISNULL(@forcedAccountId, AccountID)

    -- Return the changed rows
    SELECT AccountId, LastStartedProcessingId, Frequency, LastProcessTime, LastConfigChangeTime, ActivityType
    FROM Schedule 
    WHERE LastBatchId = @batchId

    COMMIT TRAN
END

1 ответ

Решение

Вы можете использовать блокировку приложения для обеспечения однократного выполнения. Статья ниже относится к SQL 2005, но я уверен, что решение применимо и к более новым версиям.

http://www.sqlteam.com/article/application-locks-or-mutexes-in-sql-server-2005

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