我创建了一个"队列"在sql中排序,我希望能够将项目设置为不可见,以半模拟像azure一样的队列(而不是在工作人员无法处理它的情况下立即删除它,它将再次自动出现在队列中另一个工人要去取。)
根据此SO的建议:Is T-SQL Stored Procedure Execution 'atomic'?
我在我的spDeQueue程序中包装了Begin Tran和Commit,但是我仍然遇到来自我的测试代理的重复拉动。 (他们都试图同时清空10个队列,我得到了重复读取,我不应该这样做)
这是我的特色
ALTER PROCEDURE [dbo].[spDeQueue]
@invisibleDuration int = 30,
@priority int = null
AS
BEGIN
begin tran
declare @now datetime = GETDATE()
-- get the queue item
declare @id int =
(
select top 1
[Id]
from
[Queue]
where
([InvisibleUntil] is NULL or [InvisibleUntil] <= @now)
and (@priority is NULL or [Priority] = @priority)
order by
[Priority],
[Created]
)
-- set the invisible and viewed count
update
[Queue]
set
[InvisibleUntil] = DATEADD(second, @invisibleDuration, @now),
[Viewed] = [Viewed] + 1
where
[Id] = @id
-- fetch the entire item
select
*
from
[Queue]
where
[Id] = @id
commit
return 0
END
我应该怎么做以确保这种行为是原子性的,以防止重复出列。
由于
答案 0 :(得分:1)
您的事务(即'begin trans'和'commit'之间的语句)是原子的,因为所有语句都将提交给数据库,或者都不提交。
看来你的交易与同步/互斥执行相混淆。
读入事务隔离级别,这有助于强制执行顺序执行 - 可重复读取可能会起作用。 http://en.wikipedia.org/wiki/Isolation_(database_systems)