Нужна помощь с проблемой тупика 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