代码之家  ›  专栏  ›  技术社区  ›  Goyuix

SQL Server并发性和生成的序列

  •  1
  • Goyuix  · 技术社区  · 14 年前

    我需要一个应用程序的数字序列,我希望利用SQL Server的能力来完成这项工作。我创建了以下表和过程(在SQL Server 2005中):

    CREATE TABLE sequences (
      seq_name varchar(50) NOT NULL,
      seq_value int NOT NULL
    )
    
    CREATE PROCEDURE nextval
      @seq_name varchar(50)
    AS
    BEGIN
      DECLARE @seq_value INT
    
      SET @seq_value = -1
    
      UPDATE sequences
      SET @seq_value = seq_value = seq_value + 1
      WHERE seq_name = @seq_name
    
      RETURN @seq_value
    END
    

    我有点担心,如果不锁定表/行,可能会同时发生另一个请求,并最终将相同的号码返回到另一个线程或客户机。这显然是非常糟糕的。这个设计在这方面安全吗?我是否可以添加一些可以添加必要的锁定以使其安全?

    注意:我知道在SQL Server中插入了标识—在特定情况下,这不是我要查找的内容。具体来说,我不想插入/删除行。这基本上是有一个中央表来管理一系列序列的序列号生成器。

    2 回复  |  直到 11 年前
        1
  •  4
  •   Remus Rusanu    14 年前

    更新将以独占方式锁定行,因此不会建立并发性问题。但是在UPDATE语句中使用@variable赋值依赖于未定义的行为。这是真的,它可以工作,但要依赖于定义的行为:使用output子句。

    CREATE PROCEDURE nextval
      @seq_name varchar(50)
     , @seq_value INT output
    AS
    BEGIN
      DECLARE @ot TABLE (seq_value INT)
    
      UPDATE sequences
      SET seq_value = seq_value + 1
      OUTPUT INSERTED.seq_value INTO @ot
      WHERE seq_name = @seq_name
    
      SELECT @seq_value = seq_value FROM @ot;
    END
    
        2
  •  0
  •   Baby Groot Duleendra    11 年前

    试试这个代码:

    ALTER PROCEDURE Item_Category_Details
    
    
    @Item_Category varchar(20)
    ,@Active VARCHAR(10)
    
    AS 
    
    DECLARE @Item_Category_Code varchar(20)
    DECLARE @seqNo AS INTEGER
    SELECT @seqNo=ISNULL(Item_Code,0) FROM Seq_Master
    SET @seqNo=@seqNo+1
    SET @Item_Category_Code=@seqNo
    
    PRINT @Item_Category_Code
    
    INSERT Item_Category_Master
    (Item_Category_Code
    ,Item_Category
    ,Active
    )
    VALUES
    (
    @Item_Category_Code
    ,@Item_Category
    ,@Active
    )
    UPDATE Seq_Master SET Item_Code=@seqNo