我正在寻找正确的方法来防止多个进程尝试更新表中的相同记录而导致死锁问题。我已经能够通过首先选择记录WITH (UPDLOCK)
然后进行更新来防止死锁。但是,我不确定这是否会一直有效,或者当其他进程插入新记录或更新此表中的其他记录时是否会导致其他阻塞问题。
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 :(得分:0)
首先,我不明白你为什么在转换中有你的选择查询。你没有在更新查询中使用它,所以我认为你可以把它放在外面。
然后,也许你可以尝试change your Isolation Level
SET TRANSACTION ISOLATION LEVEL
{ READ UNCOMMITTED
| READ COMMITTED
| REPEATABLE READ
| SNAPSHOT
| SERIALIZABLE
}
[ ; ]
可以尝试其中一个
READ UNCOMMITTED指定语句可以读取具有的行 已被其他交易修改但尚未提交。
REPEATABLE READ指定语句无法读取具有的数据 已被修改但尚未由其他交易承诺而且没有 其他事务可以修改当前读取的数据 交易直到当前交易完成。
SNAPSHOT指定事务中任何语句读取的数据 将是数据的事务一致版本 在交易开始时存在。交易只能 识别在开始之前提交的数据修改 交易。其他交易后的数据修改 语句不能看到当前事务的开始 在当前交易中执行。效果就像是 事务中的语句获取已提交数据的快照 在交易开始时存在。
SERIALIZABLE指定以下内容:语句无法读取数据 已被修改但尚未由其他交易承诺。没有 其他事务可以修改当前读取的数据 事务直到当前事务完成。其他 事务无法插入具有可能落入的键值的新行 当前事务中任何语句读取的键范围 直到当前交易完成。