2013-05-09 121 views
-1

我正在尋找適當的方法,以防止鎖死的問題被多個進程試圖更新表相同的記錄造成的。我已經能夠通過首先選擇記錄WITH (UPDLOCK)然後進行更新來防止死鎖。但是,我不確定這是否會一直工作,或者當其他進程插入新記錄或更新此表中的其他記錄時,它會導致其他阻塞問題。SQL服務器死鎖問題

CREATE PROCEDURE usp_ReduceOrderAmount 
      @OrderId   INT, 
      @ReductionAmount INT 
AS 
BEGIN 

SET NOCOUNT ON 

DECLARE @dDateTime AS DATETIME     
SET @dDateTime = GETUTCDATE() 

BEGIN TRANSACTION 

--Quick Fix... Attempt to block other callers who are trying to update the same record. 
SELECT * FROM ORDERS WITH (UPDLOCK) WHERE ORDER_ID = @OrderId 

UPDATE dbo.ORDERS 
SET QTY_OPEN = QTY_OPEN - @ReductionAmount, 
UPDATED_WHEN = @dDateTime 
WHERE ORDER_ID = @OrderId   

COMMIT 

END 
+0

死鎖通常涉及至少2個資源(表)。你有錯誤消息/場景? – davmos 2013-05-09 17:31:36

+0

你爲什麼選擇進入交易?爲什麼你不在交易之外? – 2013-05-09 17:38:09

+0

您還可以使用(updlock)添加更新命令 – Jimbo 2013-05-09 17:38:22

回答

0

首先,我不明白你爲什麼在轉換中有你的選擇查詢。你沒有在更新查詢中使用它,所以我認爲你可以把它放在外面。

然後,也許你可以嘗試change your Isolation Level

SET TRANSACTION ISOLATION LEVEL 
    { READ UNCOMMITTED 
    | READ COMMITTED 
    | REPEATABLE READ 
    | SNAPSHOT 
    | SERIALIZABLE 
    } 
[ ; ] 

可以嘗試之一這種

讀取未提交指定的語句可以讀取已經 被其它事務修改但尚未提交的行。

重複讀取指定語句不能讀取一個 被修改,而是由其他交易,並沒有 其他事務都不能修改已經由當前 交易,直到當前事務完成了讀取的數據還沒有提交的數據。

SNAPSHOT指定由事務 中的任何語句讀取的數據將是事務開始時存在的數據的事務一致版本。交易只能在 識別在交易開始前已提交的數據修改。當前交易開始後 之後的其他交易所做的數據修改對於在當前交易中執行的語句 不可見。其效果就好像事務中的 語句獲取提交數據的快照,因爲它在事務開始時存在。

SERIALIZABLE指定如下:語句無法讀取數據 已被修改,但其他事務尚未提交。其他事務可以修改當前事務已經讀取的數據,直到當前事務完成。其他 交易不能與將下降 任何語句在當前事務 讀取,直到當前事務完成鍵的鍵值範圍插入新行。