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

时间:2010-07-14 00:49:31

标签: tsql

我希望能够一次创建一组记录,并保证该组的标识字段是连续的(由于其他人进入并在此过程中创建记录而没有中断)。我假设某种表锁可以工作,但我不是sql guru所以任何建议都会受到赞赏(什么类型的锁?任何可能的问题?等)。

对于一点背景,表格结构非常简单......

TABLE PropertyCode
(
    Code INT IDENTITY,
    UserID INT
)

属性代码分配给属性表中的属性。可以重复使用属性代码(它们印在标志上,标志可以在多个属性之间旋转)。在符号上打印连续数字序列比随机数要便宜得多。

3 个答案:

答案 0 :(得分:1)

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRAN
SELECT * FROM PropertyCode
INSERT INTO PropertyCode ..... 
COMMIT TRAN

可序列化事务隔离模式可防止影响任何所选数据的插入/更新/删除,因此禁止SELECT * FROM PropertyCode。

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

答案 1 :(得分:1)

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

如果您使用以下内容(假设您在Code上有索引),则应该使用RangeLock来阻止其他事务在事务开始时添加代码大于最大值的新记录但不阻塞现有记录的并发更新。

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRAN
SELECT Code FROM PropertyCode WHERE Code > IDENT_CURRENT('PropertyCode')
INSERT INTO PropertyCode ..... 
COMMIT TRAN

答案 2 :(得分:0)

我不确定这是否是一个好的答案,但似乎有效...

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

我仍然可以对表进行选择,但新的插入会被锁定,直到我的sproc完成。