2

我有一个问题,当从同一个应用程序的两个不同实例同时运行同一个存储过程时,它似乎超时了,我想知道我能做些什么来解决它吗?

我相信问题出在 SQL Server 2008 处理自身、锁定行和执行 SP 的方式上……我不太了解的事情。该应用程序用于ADODB.Command执行 SP。

我有一个 VB6 exe ( App.exe),在一台服务器上多次运行。此应用程序调用数据库上的存储过程,该过程返回该应用程序的下一个序列号。此序列号字段对于应用程序的实例是唯一的 - 对于tbl_SequenceNos正在运行的应用程序的每个实例,表 ( ) 中有 1 行。

例如,假设我们正在运行:App[a].exeApp[b].exe

tblSequenceNos好像:

iAppNo| iNextSequenceNo
  a   |     1234 
  b   |     4567

获取下一个序列号的存储过程比较简单:

CREATE PROEDURE GetNextSequenceNo (@AppNo varchar(1), @NextSequenceNo int output)
AS
BEGIN
    DECLARE @TempSequenceNo int

    SELECT @NextSequenceNo = iNextSequenceNo 
    FROM tblSequenceNos 
    WHERE iAppNo = @AppNo

    @NextSequenceNo = @NextSequenceNo + 1

    UPDATE tblSequenceNos 
    SET iNextSequenceNo = @NextSequenceNo
    WHERE iAppNo = @AppNo

END

当两者都App[a].exe尝试App[b].exe运行此过程以获取它们的NextSequenceNo值时,它们会挂起大约 30 秒(ADO 超时?)。

因为每个应用程序从不查看彼此的行,所以我认为这可以同时工作而无需指定特殊的锁定。有什么我想念的吗?我想也许我需要指定只锁定行,而不是整个表或页面?- 我不知道sql2008默认是做什么的。

任何帮助是极大的赞赏!提前谢谢你,安德鲁

4

1 回答 1

2

您的过程不是线程安全的,并且会产生不正确的结果,因为在 select 和 update 之间,多个线程可能会获得相同的序列 nr。

CREATE PROCEDURE GetNextSequenceNo (@AppNo varchar(1), @NextSequenceNo int output)
AS

 DECLARE @var table(seq int);

 UPDATE tblSequenceNos 
    SET iNextSequenceNo = @NextSequenceNo + 1
 OUTPUT inserted.iNextSequenceNo INTO @var;
  WHERE iAppNo = @AppNo

  select @NextSequenceNo = seq from @var
GO  

还要确保您的 iAppNo 列已编入索引。(这意味着仅此列上的索引或该字段是索引中第一个字段的索引)

于 2011-12-01T10:58:53.023 回答