【发布时间】:2024-01-20 18:26:01
【问题描述】:
假设我有两列 CategoryId 和 SubcategoryId。对于每个 CategoryId,SubcategoryId 从 1 开始。插入新的子类别时,我需要为给定的 CategoryId 计算 MAX(SubcategoryId)+1。
下列说法正确吗?
BEGIN TRANSACTION
DECLARE @NextId bigint;
SELECT @NextId = ISNULL(MAX(SubcategoryId),0) + 1
FROM Subcategory WITH (UPDLOCK, HOLDLOCK)
WHERE CategoryId = @CategoryId;
INSERT INTO Subcategory
(
CategoryId,
SubcategoryId
)
VALUES
(
@CategoryId,
@NextId
);
COMMIT
WITH(UPDLOCK, HOLDLOCK) 是否也防止并发插入具有相同 CategoryId 的新行,还是仅锁定在 SELECT 时匹配的现有行?如果是后者,我应该将其更改为 TABLOCK 吗?是否也需要某种排他锁?
【问题讨论】:
-
能否请您发布表格定义。这会很有帮助,因为您可能不需要这样做,只需一个简单的身份。
-
表格很简单。 Subcategory(CategoryId bigint, SubcategoryId bigint) 和由两列组成的唯一键,以便 SubcategoryId 可以针对不同的 CategoryId 重复。
-
为您添加了一个可能的答案。
-
我最初在上面发布的代码是正确的解决方案。 UPDLOCK、HOLDLOCK 防止插入任何具有相同 CategoryId 的新记录。
标签: sql concurrency locking rdbms