我不得不承认我正在学习如何正确处理死锁,但根据我读过的建议,我认为这是处理它的正确方法。基本上我有很多进程试图在数据库中“保留”一行以进行更新。所以我首先阅读一个可用的行,然后写入它。这不是正确的方法吗?如果是这样,我该如何修复此SP?
CREATE PROCEDURE [dbo].[reserveAccount]
-- Add the parameters for the stored procedure here
@machineId varchar(MAX)
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN TRANSACTION;
declare @id BIGINT;
set @id = (select min(id) from Account_Data where passfail is null and reservedby is null);
update Account_data set reservedby = @machineId where ID = @id;
COMMIT TRANSACTION;
END
答案 0 :(得分:2)
您可以将其写为单个语句。这可能会解决更新问题:
update Account_data
set reservedby = @machineId
where ID = (select min(id) from Account_Data where passfail is null and reservedby is null);
答案 1 :(得分:1)
嗯,你的问题是2你有2个陈述 - 选择和更新。如果那些运行并发,则select将.....进行读锁定,更新将要求写锁定。同时2个机器死锁。
简单的解决方案是使初始选择需求成为uddate锁(WITH(ROWLOCK,UPDLOCK)作为提示)。这可能会或可能不会奏效(取决于还有什么),但这是一个良好的开端。
第二步 - 如果失败 - 是使用应用程序级别锁(sp_getapplock)来确保关键系统始终只有一个所有者,而htus只是按顺序执行事务。