2010-02-24 77 views
3

返回之前結果集我有一個簡單的表在我的SQL Server 2008數據庫:修改SQL從存儲過程

Tasks_Table 
-id 
-task_complete 
-task_active 
-column_1 
-.. 
-column_N 

對於必須由服務執行未完成任務表的指令。

我希望能夠在未來擴展我的系統。到現在爲止,只有1臺計算機上的1個服務從表中讀取。我有一個存儲過程,選擇所有未完成和不活動的任務。隨着服務開始處理任務,它將更新所有返回行中的task_active標誌。

要啓用系統擴展功能,我希望啓用更多機器上的服務部署。因爲我想阻止任務返回到多個服務,所以我必須更新返回未完成和非活動任務的存儲過程。

我想我必須鎖定表(一次只有一個讀取器 - 我知道我必須使用適當的ISOLATION LEVEL),並在返回結果集之前更新結果集每行中的task_active標誌。

所以我的問題是如何在返回之前修改存儲過程中的SELECT結果集?

回答

2

這是典型的出列圖案,使用OUTPUT子句和實現,並且在MSDN描述,請參見隊列段落中OUTPUT Clause (Transact-SQL)

UPDATE TOP(1) Tasks_Table WITH (ROWLOCK, READPAST) 
SET task_active = 1 
OUTPUT INSERTED.id,INSERTED.column_1, ...,INSERTED.column_N 
WHERE task_active = 0; 

的ROWLOCK,READPAST提示允許高吞吐量和高協調性:多線程/已處理的隊列可以在多線程/進程出隊任務的同時入隊新任務。沒有訂單保證。

更新

如果您想訂購您可以使用CTE的結果:我討論過這個和其他入隊/出隊技術的文章Using Tables as Queues

WITH cte AS (
    SELECT TOP(1) id, task_active, column_1, ..., column_N 
    FROM Task_Table WITH (ROWLOCK, READPAST) 
    WHERE task_active = 0 
    ORDER BY <order by criteria>) 
UPDATE cte 
    SET task_active = 1 
OUTPUT INSERTED.id, INSERTED.column_1, ..., INSERTED.column_N; 

+0

有沒有辦法在調用TOP(1)之前命令Task_Table而不丟失ROWLOCK和READPAST? – m0sa