SQL 服务器自定义标识列

SQL Server Custom Identity Column

我想生成一个与产品类型相关的自定义标识列。 这个查询能不能保证身份的顺序,解决并发问题。 这是一个示例查询:

BEGIN TRAN

INSERT INTO TBLKEY
VALUES((SELECT 'A-' + CAST(MAX(CAST(ID AS INT)) + 1 AS NVARCHAR) FROM TBLKEY),'EHSAN')

COMMIT

这将是一件坏事,因为无法保证两个查询 运行 同时获得的 MAX(ID) 不会是相同的值。

如果您使用标准标识列,您还可以有一个使用该列的计算列,或者在您 return 数据时仅使用 return 键。

埃德

试试这个:

BEGIN TRAN

INSERT INTO TBLKEY
VALUES((SELECT MAX(ID) + 1 AS NVARCHAR) FROM TBLKEY WITH (UPDLOCK)),'EHSAN')

COMMIT

选择最大 ID 时,您将获得该行的 U 锁。 U 锁与 U 锁不兼容,后者将尝试同时获取具有相同查询 运行ning 的另一个会话。在给定时间只会执行一个查询。 id 将有序且连续,它们之间没有任何间隙。

更好的解决方案是创建一个额外的 table 专用于存储当前或下一个 ID 并使用它而不是最大值。

您可以通过执行以下操作了解差异:

准备一个table

CREATE TABLE T(id int not null PRIMARY KEY CLUSTERED)
INSERT INTO T VALUES(1)

然后运行下面的查询在两个不同的session中一个接一个,相隔不到10秒

BEGIN TRAN
DECLARE @idv int
SELECT @idv = max (id) FROM T
WAITFOR DELAY '0:0:10'
INSERT INTO T VALUES(@idv+1)
COMMIT

稍等片刻,直到两个查询都完成。观察其中一个成功,另一个失败。

现在对以下查询执行相同的操作

BEGIN TRAN
DECLARE @idv int
SELECT @idv = max (id) FROM T WITH (UPDLOCK)
WAITFOR DELAY '0:0:5'
INSERT INTO T VALUES(@idv+1)
COMMIT

查看T的内容

DROP TABLE T

清理 T Table