在SQL Server 2008R2中管理多个获得工作分配的用户

在SQL Server 2008R2中管理多个获得工作分配的用户,sql,sql-server,concurrency,queue,Sql,Sql Server,Concurrency,Queue,我有一个SQL数据库,它有两个表,其中包含要完成的工作队列和该工作的历史记录: CREATE TABLE [dbo].[WorkQueue]( [WorkQueueID] [int] IDENTITY(1,1) NOT NULL, [BatchID] [int] NOT NULL, [AdHocProjectID] [int] NOT NULL, [TaskID] [int] NOT NULL, [CreateDate] [datetime] NOT NU

我有一个SQL数据库,它有两个表,其中包含要完成的工作队列和该工作的历史记录:

CREATE TABLE [dbo].[WorkQueue](
    [WorkQueueID] [int] IDENTITY(1,1) NOT NULL,
    [BatchID] [int] NOT NULL,
    [AdHocProjectID] [int] NOT NULL,
    [TaskID] [int] NOT NULL,
    [CreateDate] [datetime] NOT NULL,
    [CompletedDate] [datetime] NULL,
    [AlertMessage] [varchar](1024) NULL,
 CONSTRAINT [PK_WorkQueue] PRIMARY KEY CLUSTERED 
(
    [WorkQueueID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [dbo].[WorkQueueHistory](
    [WorkQueueHistoryID] [int] IDENTITY(1,1) NOT NULL,
    [WorkQueueID] [int] NOT NULL,
    [EmployeeID] [int] NOT NULL,
    [BatchBoxID] [int] NOT NULL,
    [StartTime] [datetime] NOT NULL,
    [EndTime] [datetime] NULL,
    [PercentageCompleted] [int] NOT NULL,
    [FinishedTask] [bit] NOT NULL,
    [comment] [varchar](255) NULL,
 CONSTRAINT [PK_WorkQueueHistory] PRIMARY KEY CLUSTERED 
(
    [WorkQueueHistoryID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
WorkQueue表包含需要处理的批次(作业)中的任务。用户在开始处理作业时,以及在完成作业时,会将WorkQueueHistory表中的行插入到WorkQueueHistory表中。如果任务确实已100%完成,则WorkQueueHistory表中的行将使用其结束时间进行更新,并设置FinishedTask位


我的问题是,防止两个用户启动同一任务的最佳方法是什么?现在我们没有足够的用户来解决这个问题,但是随着事情的发展,我知道如果我不解决这个问题,将会出现并发问题。

您应该使用设置了适当隔离级别的
事务


这似乎相当简单,也有道理。我需要做什么特别的隔离级别吗?这取决于:阅读主题,并考虑你的情况和数据模型如:-我已经阅读了你链接的文章。他们有点超出我的头脑,但我得到的基本知识。我必须从WorkQueue中选择以查找要插入WorkQueuehistory的合格WorkQueueID。我不知道这将如何阻止两个会话将相同的WorkQueueID插入WorkQueueHistory表。我知道在插入到WorkQueueHistory之前,我需要锁定找到的WorkQueue行,但我现在还不明白这一点。@Zuleord,视情况而定。如何确定下一个工作项是什么?这是一个相当复杂的查询,但其基本原理是我通过为某个taskid和batchid选择工作队列表来选择一个WorkQueueID,并加入workqueuehistory,其中没有历史记录endtime不为null,完成位为0。这样我就得到了一个从未使用过或当前未使用过的workqueueid。(正在处理的内容的结束时间为空)
begin tran

    -- select next job to do

    -- update job as started

commit