我正在维护一个开发人员已经实现了自己的锁定机制的sproc,但对我来说它似乎有缺陷:
CREATE PROCEDURE Sproc 1
AS
Update X
set flag = lockedforprocessing
where flag = unprocessed
-- Some processing occurs here with enough time to
-- 1. table X gets inserted new rows with a flag of unprocessed
-- 2. start another instance of this Sproc 1 that executes the above update
Select from X
where flag = lockedforprocessing
-- Now the above statement reads rows that it hadn't put a lock on to start with.
我知道我可以将它包装在隔离级别为SERIALIZABLE的事务中,但我想避免这种情况。
目标是
我认为REPEATABLE READ在这里没有帮助,因为它不会阻止读取值为“未处理”的新记录(如果我错了请纠正我)。
我刚刚发现了sp_getlock sproc,它会解决这个bug但序列化exaction,这不是我的目标。
我看到的一个解决方案是让proc的每次运行都生成自己唯一的GUID并将其分配给标志但不知何故我在想我正在模拟SQL Server已经可以开箱即用的东西。
让每个sproc进程运行的唯一方法就是“共享”行以将其设置为SERIALIZABLE吗?
问候,汤姆
答案 0 :(得分:0)
假设X中有一个ID字段,更新X的临时表可以提供帮助:
CREATE PROCEDURE Sproc 1
AS
-- Temporary table listing all accessed Xs
declare @flagged table (ID int primary key)
-- Lock and retrieve locked records
Update X
set flag = lockedforprocessing
output Inserted.ID into @flagged
where flag = unprocessed
-- Processing
Select from X inner join @flagged f on x.ID = f.ID
-- Clean-up
update X
set flag = processed
from x inner join @flagged f on x.ID = f.ID