[英]How to handle parallel bulk update requests in SQL Server?
假設我有一個存儲任務的表,該表可以具有諸如“待辦事項”,“正在處理”和“已完成”的狀態。 由於我有多個客戶來處理這些任務,因此我想確保只有一個客戶在抓取某個任務來處理它。
為了避免太多的數據庫請求,客戶端在一個請求中要處理多個(10,100,...)任務。
在SQL Server中達到此目的的最佳方法是什么?
我可以以某種方式選擇要完成的任務並同時更新它們以將其標記為“處理中”嗎?
假設您用於存儲任務的表類似於以下內容:
CREATE TABLE [TASKQUEUE]
(
[TASKID] INT ,
[CLIENTID] INT ,
[STATE] TINYINT ,
[DESCRIPTION] VARCHAR(100)
)
GO
TASKID是主鍵,CLIENTID將標記一行已由特定客戶端進行處理,STATE將包含您可能的狀態之一(“待執行”,“正在處理”,“完成”)。
然后,用於抓取任務的存儲過程可以是:
CREATE PROCEDURE [GETTASK]
@MAX INT = 100 ,
@CLIENTID INT ,
@STATE TINYINT
-- @STATE:
-- 1: to do
-- 2: processing
-- 3: done
AS
BEGIN
UPDATE [TASKQUEUE]
SET [CLIENTID] = @CLIENTID ,
[STATE] = 2
WHERE [TASKID] IN (
SELECT TOP(@MAX) [TASKID]
FROM [TASKQUEUE]
WHERE [STATE] = 1 AND [CLIENTID] IS NULL);
SELECT [TASKID] , [DESCRIPTION]
FROM [TASKQUEUE]
WHERE [CLIENTID] = @CLIENTID AND [STATE] = 2;
END;
如果您使用的是READ COMMITTED隔離級別(默認)或更高級別-UPDATE將處理多個同時請求的同步。 沒有兩個請求將能夠同時更新相同的TASKQUEUE行。 如果第二個請求嘗試在第一個請求的UPDATE之后立即調用WHERE [STATE] = 1 AND [CLIENTID] IS NULL
行已被修改,並且不會被WHERE [STATE] = 1 AND [CLIENTID] IS NULL
子句檢索。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.