以原子方式执行存储过程

时间:2014-09-24 20:56:55

标签: sql-server stored-procedures concurrency queue atomic

我创建了一个"队列"在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

我应该怎么做以确保这种行为是原子性的,以防止重复出列。

由于

1 个答案:

答案 0 :(得分:1)

您的事务(即'begin trans'和'commit'之间的语句)是原子的,因为所有语句都将提交给数据库,或者都不提交。

看来你的交易与同步/互斥执行相混淆。

读入事务隔离级别,这有助于强制执行顺序执行 - 可重复读取可能会起作用。 http://en.wikipedia.org/wiki/Isolation_(database_systems)