重试死锁查询
Retrying query on deadlocks
最近,在我们的庄园中,我们注意到某些存储过程的死锁增加了,这些非常简单:
- 插入一个 table
- 根据主键
更新table中的记录
此 table 有 太多 触发器,这些触发器偶尔会与另一个按小时运行并导致死锁的存储过程发生冲突。
我在谷歌上四处搜索,偶然发现了这篇文章: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
它几乎给了代码第二次、第三次和第四次成功的机会,然后才抛出错误。
我的问题是,这是否是一种在紧张情况下处理死锁的健康模式,是否是一个实际的解决方案,而不是解决问题的方法?
免责声明:此答案仅供参考:)
这个解决方案看起来对我有用。但是,我不认为这是一个实际的解决方案,而是一种解决方法。相反,最好尝试找出导致死锁的原因并解决它。
如果您无法解决死锁的原因,那么像这样的变通办法也不会太糟糕,但实际上只是在解决实际问题。
最近,在我们的庄园中,我们注意到某些存储过程的死锁增加了,这些非常简单:
- 插入一个 table
- 根据主键 更新table中的记录
此 table 有 太多 触发器,这些触发器偶尔会与另一个按小时运行并导致死锁的存储过程发生冲突。
我在谷歌上四处搜索,偶然发现了这篇文章: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
它几乎给了代码第二次、第三次和第四次成功的机会,然后才抛出错误。
我的问题是,这是否是一种在紧张情况下处理死锁的健康模式,是否是一个实际的解决方案,而不是解决问题的方法?
免责声明:此答案仅供参考:)
这个解决方案看起来对我有用。但是,我不认为这是一个实际的解决方案,而是一种解决方法。相反,最好尝试找出导致死锁的原因并解决它。
如果您无法解决死锁的原因,那么像这样的变通办法也不会太糟糕,但实际上只是在解决实际问题。