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

在TSQL中,在标识字段上按顺序创建一组记录的最佳方法是什么?

  •  3
  • skolima  · 技术社区  · 15 年前

    我希望能够一次创建一组记录,并保证组的标识字段是连续的(在这个过程中,不会因为其他人进来创建记录而中断)。我假设某种类型的表锁可以工作,但我不是sql专家,所以任何建议都会很感激(什么类型的锁?有什么问题吗?等等)。

    作为一个小背景,表结构非常简单。。。

    TABLE PropertyCode
    (
        Code INT IDENTITY,
        UserID INT
    )
    

    3 回复  |  直到 15 年前
        1
  •  1
  •   Chris Diver    15 年前
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    BEGIN TRAN
    SELECT * FROM PropertyCode
    INSERT INTO PropertyCode ..... 
    COMMIT TRAN
    

    可序列化事务隔离模式防止插入/更新/删除会影响任何选定的数据,因此选择*来自属性代码。

    主要问题是,在提交事务之前,其他进程不能更新/插入/删除。

        2
  •  1
  •   Martin Smith    15 年前

    我认为克里斯的回答可以改进。当前它将选择并锁定整个表内容。

    如果您使用以下(并且假设您在 Code )它应该只使用RangeLock来防止其他事务在事务开始时添加代码大于最高值的新记录,但不阻止对现有记录的并发更新。

    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    BEGIN TRAN
    SELECT Code FROM PropertyCode WHERE Code > IDENT_CURRENT('PropertyCode')
    INSERT INTO PropertyCode ..... 
    COMMIT TRAN
    
        3
  •  0
  •   skolima    15 年前

    我不确定这是不是一个好的答案,但它似乎工作。。。

    CREATE PROCEDURE ReservePropertyCodes
        @Count INT,
        @UserID INT
    AS
    
    DECLARE @i INT
    
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    BEGIN TRANSACTION
    
    -- Locks the table
    SELECT TOP 1 * FROM PropertyCode WITH (TABLOCK)
    
    SET @i = 0
    WHILE @i < @Count
    BEGIN
        INSERT INTO PropertyCode (UserID) VALUES (@UserID)
        SET @i = @i + 1 
    END
    COMMIT TRANSACTION