gpt4 book ai didi

database-design - SQL并发测试更新问题

转载 作者:行者123 更新时间:2023-12-01 05:45:43 25 4
gpt4 key购买 nike

我有一个 SQLServer 2008 数据库,其中有一个标签表。标签只是一个 id 和一个名称。标签表的定义如下所示:

CREATE TABLE [dbo].[Tag](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](255) NOT NULL
CONSTRAINT [PK_Tag] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON)
)

名称也是唯一索引。此外,我有几个进程以相当快的速度向该表添加数据。这些进程使用如下所示的存储过程:
ALTER PROC [dbo].[lg_Tag_Insert]
@Name varchar(255)
AS


DECLARE @ID int
SET @ID = (select ID from Tag where Name=@Name )

if @ID is null
begin
INSERT Tag(Name)
VALUES (@Name)

RETURN SCOPE_IDENTITY()

end
else
begin
return @ID
end

我的问题是,除了作为并发数据库设计的新手之外,似乎存在竞争条件,导致我偶尔会收到错误,即我试图将重复键(名称)输入到数据库中。错误是:

无法在具有唯一索引“IX_Tag_Name”的对象“dbo.Tag”中插入重复的键行。

这是有道理的,我只是不知道如何解决这个问题。如果它在哪里代码,我会知道如何锁定正确的区域。 SQLServer 是一个完全不同的野兽。

第一个问题是编码此“检查,然后更新模式”的正确方法是什么?似乎我需要在检查期间获得该行的排他锁,而不是共享锁,但我不清楚这样做的最佳方法。任何在正确方向上的帮助将不胜感激。提前致谢。

最佳答案

我更喜欢输出参数(所以我这样编码),但这应该执行得最快,在 table 上的点击次数最少:

ALTER PROC [dbo].[lg_Tag_Insert]
@Name varchar(255)
,@ID int OUTPUT
AS
BEGIN TRY
SET @ID=NULL
INSERT Tag (Name) VALUES (@Name)
SET @ID=SCOPE_IDENTITY()
END TRY
BEGIN CATCH
SELECT @ID=ID from Tag where Name=@Name
END CATCH

IF @ID IS NULL
BEGIN
RETURN 1
END

RETURN 0

GO

关于database-design - SQL并发测试更新问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2494829/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com