首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

大家好,请问SQL行锁的有关问题,在存储过程中

2014-01-05 
大家好,请教SQL行锁的问题,在存储过程中。业务逻辑:查出一条Task记录,缓存Id,将这条记录更新为当前时间,然

大家好,请教SQL行锁的问题,在存储过程中。
业务逻辑:查出一条Task记录,缓存Id,将这条记录更新为当前时间,然后返回这条记录。
问题:当很多用户并发这个存储过程时,数据就会不一致。

现在想要解决并发,就是select到update这一个步骤,请问该怎么加锁呢?

存储过程代码:


BEGIN

DECLARE @tmpId INT;

--在这里开始上锁,独占这一行,不允许其他用户查询这一行
SELECT TOP 1 @tmpId=Id
FROM Task
WHERE DATEDIFF(mi,t.Last_Work_Time,GETDATE())> Interval_Time
ORDER BY Id ASC ;

UPDATE Task SET Last_Work_Time=GETDATE() WHERE Id=@tmpId;
--更新之后,解锁

SELECT Id,Keyword,Interval_Time,Last_Work_Time FROM Task WHERE Id=@tmpId;

END

[解决办法]
改成这样试试:

BEGIN
 
    DECLARE @tmpId INT;
 
    --在这里开始上锁,独占这一行,不允许其他用户查询这一行
    SELECT TOP 1 @tmpId=Id
    FROM Task with(xlock)    --加了独占锁
    WHERE DATEDIFF(mi,t.Last_Work_Time,GETDATE())> Interval_Time
    ORDER BY Id ASC ;
 
    UPDATE Task SET Last_Work_Time=GETDATE() WHERE Id=@tmpId;
    --更新之后,解锁
 
    SELECT Id,Keyword,Interval_Time,Last_Work_Time FROM Task WHERE Id=@tmpId;
 
END

[解决办法]

BEGIN
    DECLARE @tmp table (tmpId INT)

    BEGIN tran
    UPDATE Task SET Last_Work_Time=GETDATE() 
    OUTPUT Inserted.ID INTO @tmp
    WHERE Id=
    (
    SELECT TOP 1 Id
    FROM Task
    WHERE DATEDIFF(mi,t.Last_Work_Time,GETDATE())> Interval_Time
    ORDER BY Id ASC
    )
    COMMIT TRAN
 
    SELECT Id,Keyword,Interval_Time,Last_Work_Time FROM Task 
    WHERE Id=(SELECT tmpId from @tmp)
END

[解决办法]

BEGIN
    DECLARE @tmp table (Id INT,Keyword VARCHAR(MAX),Interval_Time datetime,Last_Work_Time DATETIME)
 
    BEGIN tran
    UPDATE Task SET Last_Work_Time=GETDATE() 
    OUTPUT Inserted.ID,Inserted.Keyword,Inserted.Interval_Time,Inserted.Last_Work_Time INTO @tmp
    WHERE Id=
    (
    SELECT TOP 1 Id
    FROM Task
    WHERE DATEDIFF(mi,t.Last_Work_Time,GETDATE())> Interval_Time
    ORDER BY Id ASC
    )
    COMMIT TRAN
      
    SELECT * FROM @tmp
END

热点排行