SQL Server 2008存储过程并发运行导致延迟

时间:2011-12-01 10:48:32

标签: sql-server-2008 stored-procedures isolation-level table-locking database-locking

我遇到一个问题,似乎当同一个应用程序的两个不同实例同时运行相同的存储过程时,它会超时,并且想知道我能做些什么来解决它?

我认为问题在于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].exeApp[b].exe尝试运行此过程以获取NextSequenceNo值时,它们会挂起大约30秒(ADO超时?)。

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

非常感谢任何帮助! 先感谢您 安德鲁

1 个答案:

答案 0 :(得分:2)

您的过程不是线程安全的,并且会产生不正确的结果,因为在select和更新之间,多个线程可能会得到相同的序列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列已编制索引。 (这意味着仅此列的索引或此字段是索引中第一个字段的索引)