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
Sql server 如何在不使用while循环或递归的情况下实现并发性?_Sql Server_Tsql_Concurrency - Fatal编程技术网

Sql server 如何在不使用while循环或递归的情况下实现并发性?

Sql server 如何在不使用while循环或递归的情况下实现并发性?,sql-server,tsql,concurrency,Sql Server,Tsql,Concurrency,我有一个表,它的复合ID有两个键:ItemType可以是以下“BIG”、“MED”、“SML”和ItemNumber中的一个,ItemNumber可以是0-9999范围内的任何数字。分配的目标是管理并发性,以便表的INSERT请求正确且不重复,如下所示:BIG0001、BIG0002、BIG0003。此外,该表还有一个Int类型的RowNumber列,用于对教师布置的问题进行分组 我读过几篇关于这个主题的SQLServer文章,不知怎么地,我成功地得到了一个工作示例,但我觉得这可以做得更好。我实

我有一个表,它的复合ID有两个键:ItemType可以是以下“BIG”、“MED”、“SML”和ItemNumber中的一个,ItemNumber可以是0-9999范围内的任何数字。分配的目标是管理并发性,以便表的INSERT请求正确且不重复,如下所示:BIG0001、BIG0002、BIG0003。此外,该表还有一个Int类型的RowNumber列,用于对教师布置的问题进行分组

我读过几篇关于这个主题的SQLServer文章,不知怎么地,我成功地得到了一个工作示例,但我觉得这可以做得更好。我实际上在使用try/catch块和递归。为什么?因为我得到的是死锁,一旦抛出死锁,它就会落入陷阱,然后我再次执行存储过程。但是这种方法产生了一个问题:堆栈大小。存储过程调用有一个确定的堆栈大小,如果通过150次并发执行,我会因此得到一个错误

这是我的代码:

创建表项 RowNumber INT不为空, ItemNumber INT不为空, ItemType CHAR3不为空, 约束ItemTypeEnum CHECKItemType位于“大”、“中”、“SML”, 约束MaxItemNumber CHECKItemNumber介于0和9999之间, 主键ItemNumber,ItemType ; 去 创建或更改过程RegisterItem@ItemType CHAR3 像 开始 开始尝试 将事务隔离级别设置为可序列化; 开始事务[注册表项] 声明@LastRowNumber INT; 声明@LastItemNumber INT; 选择@LastRowNumber=COALESCESELECT TOP 1 RowNumber FROM Item WITH HOLDLOCK,ROWLOCK其中ItemType=@ItemType ORDER BY RowNumber DESC,0+1; 选择@LastItemNumber=COALESCESELECT TOP 1 ItemNumber FROM Item WITH HOLDLOCK,ROWLOCK,其中ItemType=@ItemType ORDER BY RowNumber DESC,0+1; 插入到CamionItemType、RowNumber、ItemNumber中VALUES@ItemType,@LastRowNumber,@LastItemNumber; 提交事务[RegisterItem] 结束尝试 开始捕捉 回滚事务[RegisterItem]; EXEC RegisterItem@ItemType 端接 终止 去
我在NodeJS中编写了一个小脚本,它向服务器发送100个并发请求,我得到了超过最大存储过程堆栈大小的错误,有时还出现死锁。比如说,我如何实现发送请求的最大数量,即每个项目发送9999个请求,而不出现错误、重复信息或信息丢失?

您可以尝试此方法。您可以直接调用use INSERT…SELECT在表中插入记录,而不是将值保存在变量中然后使用它进行保存



CREATE OR ALTER PROCEDURE RegisterItem @ItemType CHAR(3)
AS
  BEGIN
      BEGIN TRY
          SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
          BEGIN TRANSACTION [RegisterItem]
            INSERT INTO Camion(ItemType, RowNumber, ItemNumber)    ---- here are you sure your table name is correct 
            SELECT @ItemType, ISNULL(MAX(RowNumber)+1,1), ISNULL(MAX(ItemNumber)+1,1) FROM Item WHERE ItemType = @ItemType GROUP BY ItemType

          COMMIT TRANSACTION [RegisterItem]
      END TRY
      BEGIN CATCH
          ROLLBACK TRANSACTION [RegisterItem];
          EXEC RegisterItem @ItemType    ---- why you are calling this again..?
      END CATCH
  END


你可以试试这个。您可以直接调用use INSERT…SELECT在表中插入记录,而不是将值保存在变量中然后使用它进行保存



CREATE OR ALTER PROCEDURE RegisterItem @ItemType CHAR(3)
AS
  BEGIN
      BEGIN TRY
          SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
          BEGIN TRANSACTION [RegisterItem]
            INSERT INTO Camion(ItemType, RowNumber, ItemNumber)    ---- here are you sure your table name is correct 
            SELECT @ItemType, ISNULL(MAX(RowNumber)+1,1), ISNULL(MAX(ItemNumber)+1,1) FROM Item WHERE ItemType = @ItemType GROUP BY ItemType

          COMMIT TRANSACTION [RegisterItem]
      END TRY
      BEGIN CATCH
          ROLLBACK TRANSACTION [RegisterItem];
          EXEC RegisterItem @ItemType    ---- why you are calling this again..?
      END CATCH
  END


看起来您的rownumber和itemnumber总是具有相同的值,因为它们都是由+1同时更新的。是的,它们是这样的@暗室。由于这两个元素都从0开始,一直到9999,我不明白为什么它们不应该总是相同的。还是有什么我看不到的?请将重试机制置于此SP之外,以避免嵌套限制。如果我创建了另一个调用RegisterItem one的存储过程并检查失败情况,然后再次调用自己,是否正确?是的,创建另一个SP,从循环调用此存储过程,直到成功或通过最大尝试次数。这样您就不会尝试嵌套。或者在代码中这样做。看起来您的rownumber和itemnumber总是具有相同的值,因为它们都是由+1同时更新的。是的,它们是@暗室。由于这两个元素都从0开始,一直到9999,我不明白为什么它们不应该总是相同的。还是有什么我看不到的?请将重试机制置于此SP之外,以避免嵌套限制。如果我创建了另一个调用RegisterItem one的存储过程并检查失败情况,然后再次调用自己,是否正确?是的,创建另一个SP,从循环调用此存储过程,直到成功或通过最大尝试次数。这样您就不会尝试嵌套。抱歉,这个表是用西班牙语写的,所以我把它和存储过程翻译成了英语哈哈。我试试你的例子,谢谢!。我再次从自身调用存储过程,因为当并发请求到达时,我会出现死锁,执行停止。所以,当我因为这个错误而再次调用存储过程作为重试策略。对不起,这个表是用西班牙语写的,所以我把它和存储过程翻译成了英语哈哈。我试试你的例子,谢谢!。我再次从自身调用存储过程,因为当并发请求到达时,我会出现死锁,执行停止。因此,当我由于该错误而收到错误时,我再次调用存储过程作为重试策略。