У меня есть база данных SQLServer 2008, в которой у меня есть таблица для тегов. Тег - это просто идентификатор и имя. Определение таблицы тегов выглядит следующим образом:
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
Моя проблема в том, что, помимо того, что я новичок в параллельном проектировании базы данных, кажется, что есть условие гонки, которое заставляет меня иногда получать ошибку, что я пытаюсь ввести дубликаты ключей (Имя) в БД. Ошибка:
Невозможно вставить строку повторяющегося ключа в объект 'dbo.Tag' с уникальным индексом 'IX_Tag_Name'.
Это имеет смысл, я просто не уверен, как это исправить. Если это где код, я бы знал, как заблокировать правильные области. SQLServer - это совсем другой зверь.
Первый вопрос: как правильно кодировать эту «проверку, а затем обновлять шаблон»? Кажется, мне нужно получить эксклюзивную блокировку строки во время проверки, а не общую блокировку, но мне не совсем понятен лучший способ сделать это. Любая помощь в правильном направлении будет принята с благодарностью. Заранее спасибо.