Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从数据库中选择并发任务_C#_Sql Server_Database_Concurrency - Fatal编程技术网

C# 从数据库中选择并发任务

C# 从数据库中选择并发任务,c#,sql-server,database,concurrency,C#,Sql Server,Database,Concurrency,在数据库表中,我保存了一个任务列表。为了简单起见,假设任务是一个整数,并让表中有100个整数以递增的顺序排列。(增加顺序意味着如果有人正在处理任务N,则所有

在数据库表中,我保存了一个任务列表。为了简单起见,假设任务是一个整数,并让表中有100个整数以递增的顺序排列。(增加顺序意味着如果有人正在处理任务N,则所有 我还有5个客户端,它们连接并从数据库中选择任务,并在任务完成时更新数据库

我不希望任何两个客户选择相同的任务

每当选择任务时,我都将其添加到另一个表“tasksTable”中。在选择新任务时,我在“tasksTable”中找到max_int,然后选择任务=max_int+1

为了避免工作重复,我将挑选任务的过程序列化,即

getlock
read max_int
pick task
update tasksTable
releaselock

因为我只有大约10名员工,所以连载并不是什么大问题。如果我有1000个客户呢。如何使任务拾取并行化?

您可以尝试使用锁定,但可以通过更新/选择来解决此问题:

BEGIN TRAN

UPDATE Task
SET clientId = MyClientId
WHERE [PrimaryKey] = (
   SELECT TOP 1 [PrimaryKey]
   FROM Tasks
   WHERE clientId IS NULL
   ORDER BY CreationDateTime)

SELECT * FROM Tasks
WHERE [PrimaryKey] = MyClientId

COMMIT TRAN
像这样的


或者可以使用OUPUT子句:

DECLARE @TaskId AS INT

UPDATE TOP(1) Task
SET clientId = MyClientId
OUTPUT Task.[PrimaryKey] INTO @TaskId
WHERE clientId IS NULL
ORDER BY CreationDateTime

SELECT @TaskId
(未对其进行测试)


来源:

您可以尝试使用锁,但您可以通过更新/选择来解决此问题:

BEGIN TRAN

UPDATE Task
SET clientId = MyClientId
WHERE [PrimaryKey] = (
   SELECT TOP 1 [PrimaryKey]
   FROM Tasks
   WHERE clientId IS NULL
   ORDER BY CreationDateTime)

SELECT * FROM Tasks
WHERE [PrimaryKey] = MyClientId

COMMIT TRAN
像这样的


或者可以使用OUPUT子句:

DECLARE @TaskId AS INT

UPDATE TOP(1) Task
SET clientId = MyClientId
OUTPUT Task.[PrimaryKey] INTO @TaskId
WHERE clientId IS NULL
ORDER BY CreationDateTime

SELECT @TaskId
(未对其进行测试)


来源:

假设两个表,一个用于未勾选的任务(WaitingTasks),一个用于勾选的“进行中”任务(WorkingTasks):

并行任务拾取可以这样完成:

INSERT INTO WorkingTasks (WaitingTaskID)
SELECT TOP 1 WaitingTaskID
FROM WaitingTasks
WHERE WaitingTaskID NOT IN (SELECT WaitingTaskID FROM WorkingTasks);

SELECT SCOPE_IDENTITY();

这将创建一个具有自己唯一ID的新“工作任务”,SCOPE_IDENTITY()将向您返回该唯一ID。

假设有两个表,一个用于未点击的任务(WaitingTasks),一个用于点击的“进行中”任务(工作任务):

并行任务拾取可以这样完成:

INSERT INTO WorkingTasks (WaitingTaskID)
SELECT TOP 1 WaitingTaskID
FROM WaitingTasks
WHERE WaitingTaskID NOT IN (SELECT WaitingTaskID FROM WorkingTasks);

SELECT SCOPE_IDENTITY();

这将创建一个具有自己唯一ID的新“工作任务”,SCOPE_IDENTITY()将向您返回该唯一ID。

不太了解您在这里所做的工作。在任务完成之前,是否锁定数据库表中的记录?如果是这样,我认为这不是一个好主意。相反,在任务数据库表中添加一列来提供任务的状态如何?如果已签出,则将其设置为true,否则将其设置为false。或者,您可以添加一列,指示签出对象(他的personID)。如果为空,则不会向任何人签出。注意:在这个解决方案中,您只有一个任务数据库表,而不是两个(一个单独的用于已完成任务的数据库表)。我认为这是一个更好的解决方案(更好的标准化)

仅向尚未分配的用户显示任务。如果他选择了一个,并且有人在他有机会点击更新按钮之前就击败他注册了该任务,你可以在更新时通知他已经太晚了。示例:此SQL中的“where”子句执行以下操作:“更新任务集personID=233421,其中personID==null”。如果更新返回时没有更新任何记录,则您知道发生了什么

我认为您的数据库/程序在支持数千个用户方面不会有任何问题,因为只有当多个用户在相同的几毫秒内更新任务表时,在第一次更新完成之前才会有轻微的延迟。即使如此,对于1000个用户,我怀疑会有超过10个左右的用户同时单击更新(几毫秒乘以10仍然不是很多时间)

另外,我认为您应该让数据库生成一个新的任务号,而不是通过task=max_int+1以编程方式进行。这样您就不必锁定表以确保在更新之前它不会更改。另请注意:如果每次更新都需要更新多个表,请设置一个事务。您不需要为一次表更新执行此操作


最后注意:处理更新的一个通用解决方案是向表中添加一个“版本”列(整数或长),并在每次有人更新记录时增加该列。然后,对于每个更新,查看版本号是否与上次读取时相同(SQL:update tasks set personID=233421,其中版本=4)。如果不一样,请通知用户。

不太明白您在这里做什么。在任务完成之前,是否锁定数据库表中的记录?如果是这样,我认为这不是一个好主意。相反,在任务数据库表中添加一列来提供任务的状态如何?如果已签出,则将其设置为true,否则将其设置为false。或者,您可以添加一列,指示签出对象(他的personID)。如果为空,则不会向任何人签出。注意:在这个解决方案中,您只有一个任务数据库表,而不是两个(一个单独的用于已完成任务的数据库表)。我认为这是一个更好的解决方案(更好的标准化)

仅向尚未分配的用户显示任务。如果他选择了一个,并且有人在他有机会点击更新按钮之前就击败他注册了该任务,你可以在更新时通知他已经太晚了。示例:此SQL中的“where”子句执行以下操作:“更新任务集personID=233421,其中personID==null”。如果更新返回时没有更新任何记录,则您知道发生了什么

我认为您的数据库/程序在支持数千个用户方面不会有任何问题,因为只有当多个用户在相同的几毫秒内更新任务表时,在第一次更新完成之前才会有轻微的延迟。即使如此,对于1000个用户,我怀疑会有超过10个左右的用户同时单击更新(几毫秒乘以10仍然不是很多时间)

另外,我认为您应该让数据库生成一个新的任务号,而不是通过task=max_int+1以编程方式进行。这样您就不必锁定表以确保在更新之前它不会更改。另请注意:如果每次更新都需要更新多个表,请设置一个事务。您不需要为一次表更新执行此操作

最后一点注意:处理更新的一个通用解决方案是在表中添加一个“version”列(整数或长),并在每次有人更新时增加它