【发布时间】:2012-12-28 20:48:57
【问题描述】:
寻求帮助解决这个死锁问题...我有一个存储过程,它被许多进程相当频繁地调用,但在一个小表上(行数低至数千)...偶尔,我在 proc 上遇到了死锁。
Proc 的目的是返回下一个“符合处理条件”的行。不将同一行返回给 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
【问题讨论】:
-
您是否有权获取死锁图,它会告诉您为什么会发生死锁? (抱歉,从来没有搞砸过 Azure,所以不知道是否可以访问。)
-
如果没有死锁图,我会尝试将
WITH(UPDLOCK)提示添加到最后一个选择语句。 -
不要以为我可以得到死锁图。 WITH(UPDLOCK) 语句不起作用,实际上它使事情变得更糟 - 它用 batchId 标记了某些行,但没有返回它们
标签: sql sql-server deadlock database-deadlocks