以下sproc嘗試向表中插入一行並生成隨機ID,該ID用於相應表上的PK。在catch塊中處理隨機生成的ID的衝突,在該塊中再次重試/調用該過程。現在,這需要很長時間,並導致死鎖,因爲鎖定會保留很長一段時間。有沒有辦法在重試之前立即釋放死鎖,以便在其他線程可以成功鎖定PK索引時出現一個短窗口?重試INSERT引起的死鎖
CREATE PROCEDURE addPerson
(
@FirstName nvarchar(100),
@LastName nvarchar(100)
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @PersonId int
-- generate random PersonId
-- this sproc can generate ids that already exist in the table
EXEC generateRandomPersonId @[email protected] OUTPUT
BEGIN TRY
INSERT INTO [dbo].[Persons]
(
PersonId,FirstName,LastName
)
VALUES
(
@PersonId,@FirstName,@LastName
)
BEGIN CATCH
--
-- HOW TO RELEASE LOCKS HERE that are still held
-- for the previous INSERT statement?
--
DECLARE @ErrorNumber int, @ErrorMessage nvarchar(2048)
SELECT @ErrorNumber=ERROR_NUMBER(),
@ErrorMessage=ERROR_MESSAGE()
-- if a race condition happened and
-- PersonId happened to be picked already, retry all over again
IF (@ErrorNumber = 2601 OR @ErrorNumber = 2627 AND CHARINDEX(N'PK_Persons_PersonId', @ErrorMessage) > 0)
BEGIN
--
-- RETRYING HERE participates in a high possibility and
-- occurrence of deadlocks
--
EXEC addPerson @FirstName,@LastName
END
ELSE
-- some other error, rethrow it
EXEC rethrowError
END
END CATCH
END
GO
這是一個COMERCIAL或生產環境產品? – danihp 2011-12-19 20:49:38
怎麼會有一個唯一的違反約束的錯誤代碼?我根本不知道SQL服務器,只是好奇而已 – fge 2011-12-19 20:50:21
爲什麼不使用[transactions](http://beyondrelational.com/blogs/nakul/archive/2011/02/24/exception-handling-in-t-sql - 嘗試 - 追趕懷才不遇的功能 - 的 - 微軟SQL-server.aspx)?在'try'和rollback之前開始事務,你寫評論_如何發佈...。 – danihp 2011-12-19 20:57:21