2014-09-24 48 views
0

我已經在sql中創建了一個排序「隊列」,我希望能夠將一個項目設置爲不可見以半模擬一個天藍色的隊列(而不是在工作人員無法處理它,它會自動出現在隊列中供其他工作人員讀取)。原子執行存儲過程

按照建議從這個SO:Is T-SQL Stored Procedure Execution 'atomic'?

我包的begin tran,並承諾在我spDeQueue程序,但我仍然運行到重複的從我的測試劑拉。 (他們都試圖同時空的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 

我應該怎麼做,以確保此行爲atomicly ,以防止重複出隊。

感謝

回答

1

您的交易(即間「開始反式」和「承諾」語句)是在這個意義上,要麼所有的語句將被提交到數據庫,要麼都不原子。

看來你有事務與同步/互斥執行混淆。

讀入事務隔離級別應該有助於強制執行順序執行 - 可重複讀取可能會有所訣竅。 http://en.wikipedia.org/wiki/Isolation_(database_systems)

+0

這似乎工作,但我收到一些例外,可能死鎖。我會調試一下,並進一步弄清楚事情。 – ohmusama 2014-09-24 21:40:50

+0

'無法訪問隊列:事務(進程ID 60)在鎖定資源上與另一個進程死鎖並被選爲死鎖犧牲品。重新運行交易。' 這是正常的嗎? – ohmusama 2014-09-24 21:52:05

+0

好吧把它修改爲'serializable'(來自'repeatable read'),它現在看起來並沒有死鎖,謝謝。 – ohmusama 2014-09-24 22:02:55