2013-05-09 66 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指定如下:语句无法读取数据 已被修改,但其他事务尚未提交。其他事务可以修改当前事务已经读取的数据,直到当前事务完成。其他 交易不能与将下降 任何语句在当前事务 读取,直到当前事务完成键的键值范围插入新行。