重试查询死锁

时间:2017-02-27 19:27:38

标签: sql-server deadlock database-deadlocks

最近,在我们的产业中,我们注意到某些存储过程中死锁的增加,这些非常简单:

  • 插入表格
  • 根据主键更新表中的记录

此表有太多触发器,并且这些触发器与另一个存储过程偶尔发生冲突,该存储过程每小时运行一次并导致死锁。

我正在谷歌上搜索这篇文章:https://www.simple-talk.com/sql/database-administration/handling-deadlocks-in-sql-server/

它建议使用以下模式来处理死锁程序:

DECLARE @retries INT ;
SET @retries = 4 ;

WHILE ( @retries > 0 ) 
    BEGIN
        BEGIN TRY
            BEGIN TRANSACTION ;

         -- place sql code here
            SET @retries = 0 ;

            COMMIT TRANSACTION ;
        END TRY
        BEGIN CATCH 
        -- Error is a deadlock
            IF ( ERROR_NUMBER() = 1205 ) 
                SET @retries = @retries - 1 ;

        -- Error is not a deadlock
            ELSE 
                BEGIN
                    DECLARE @ErrorMessage NVARCHAR(4000) ;
                    DECLARE @ErrorSeverity INT ;
                    DECLARE @ErrorState INT ;

                    SELECT  @ErrorMessage = ERROR_MESSAGE() ,
                            @ErrorSeverity = ERROR_SEVERITY() ,
                            @ErrorState = ERROR_STATE() ;

                    -- Re-Raise the Error that caused the problem
                    RAISERROR (@ErrorMessage, -- Message text.
                       @ErrorSeverity, -- Severity.
                       @ErrorState -- State.
                       ) ;
                    SET @retries = 0 ;
                END

            IF XACT_STATE() <> 0 
                ROLLBACK TRANSACTION ;
        END CATCH ;
    END ;
GO 

它几乎为代码提供了成功的第二,第三和第四次机会,然后才会抛出错误。

我的问题是,这是否是一种处理前卫情况下死锁的健康模式,是一种实际的解决方案,而不是解决问题的方法?

1 个答案:

答案 0 :(得分:0)

免责声明:这个答案只是一个意见:)

这个解决方案看起来对我有用。但是,我不认为这是一个实际的解决方案,而是一种解决方法。最好是尝试找出造成你的死锁的原因并解决这个问题。

如果你无法解决僵局的原因,那么像这样的解决方案并不可怕,但真正只是解决实际问题。