3

我遇到以下存储过程的间歇性死锁。它每分钟运行一次。它已经投入生产 1 年多,我们通常不会收到此错误,但有时会突然出现......它在我们的一个环境中每天抛出 3 到 5 次异常......它与其他实例的环境相同没有抛出错误。存储过程是这样创建的,所以它一次只能运行一次,但也许我们这样做的方式不正确?

这是错误:

System.Web.HttpUnhandledException:引发了“System.Web.HttpUnhandledException”类型的异常。---> System.Data.SqlClient.SqlException:事务(进程 ID 60)在锁定资源上与另一个进程死锁,并已被选为死锁受害者。重新运行事务。

这是存储过程:

 SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[requestUpdate]
AS
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

BEGIN TRAN
    DECLARE @StartDate datetime,
            @EndDate datetime,
            @Throttle bit,
            @Expired bit

    SELECT @Throttle = 0
    SELECT @Expired = 0

    SELECT TOP 1 @StartDate = uq.StartDate, @EndDate = uq.EndDate
      FROM UpdateQueue uq WITH(TABLOCK,XLOCK)
     ORDER BY ID DESC

    -- PREVENT ANOTHER REQUEST IF THIS SP HAS BEEN
    -- CALLED IN THE LAST FORTY SECONDS.
    IF DATEADD(SECOND,-40,GETDATE()) < @StartDate
    BEGIN
      SELECT @Throttle = 1
    END

    -- CREATE ANOTHER REQUEST IF THE CURRENT ONE
    -- HAS NOT COMPLETED IN THE LAST FIVE MINUTES.
    IF @StartDate <= DATEADD(MINUTE,-5,GETDATE())
    BEGIN
      SELECT @Expired = 1
    END

    -- HAS THE CURRENT REQUEST EXPIRED?
    IF @EndDate IS NULL AND @Expired = 1
    BEGIN
      INSERT INTO UpdateQueue (RequestID, StartDate) OUTPUT 'EXPIRED' AS Result, INSERTED.RequestID AS RequestID
      VALUES (NEWID(), GETDATE())
    END

    -- HAS THE CURRENT REQUEST COMPLETED AND YOU ARE NOT THROTTLING
    -- OR HAVE THERE NOT BEEN ANY REQUESTS YET?
    ELSE IF (@EndDate IS NOT NULL AND @Throttle = 0) OR @StartDate IS NULL
    BEGIN
      INSERT INTO UpdateQueue (RequestID, StartDate) OUTPUT 'STARTED' AS Result, INSERTED.RequestID AS RequestID
      VALUES (NEWID(), GETDATE())
    END

    -- Running
    ELSE
    BEGIN
      SELECT 'RUNNING' AS Result, NULL AS RequestID
    END

COMMIT
4

1 回答 1

0

我怀疑这是一个特定的锁被持有的时间超过了您的连接愿意等待的时间。如果没有东西可以终止长时间运行的事务,在这里,您将遇到这种情况,因为当连接超时时,SQL Server 会强制等待结束并终止作为死锁受害者的传入锁。

长话短说:某个进程(此处未详述)正在锁定表,从而导致死锁。

检查当您遇到死锁时还发生了什么 - 是否有备份正在运行,或者其他锁定该表的东西?

于 2013-02-15T17:47:40.660 回答