如何在SQL Server中处理并行批量更新请求?

时间:2014-03-27 11:28:56

标签: c# sql-server multithreading locking

我们假设我有一个存储任务的表格,这些表格可能具有类似的状态,即“处理”和“处理”状态。并且“完成了”。由于我有多个客户负责处理这些任务,我想确保只有一个客户抓住某个任务来处理它。

为了避免过多的数据库请求,客户端会在一个请求中处理多个(10,100,...)任务。

在SQL Server中实现此目的的最佳方法是什么?

我能否以某种方式选择要完成的任务并同时更新它们以将其标记为“处理”?

1 个答案:

答案 0 :(得分:0)

假设您存储任务的表与此类似:

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子句将不会检索。