У меня проблемы с параллелизмом при вставке в хранимую процедуру. Соответствующая часть процедуры такова:
select @_id = Id from table1 where othervalue = @_othervalue
IF( @_id IS NULL)
BEGIN
insert into table1 (othervalue) values (@_othervalue)
select @_id = Id from table1 where othervalue = @_othervalue
END
Когда мы запускаем 3 или 4 из этих сохраненных процедур одновременно, мы иногда получаем несколько вставок.
Я планирую исправить это так:
insert into table1 (othervalue)
select TOP(1) @_othervalue as othervalue from table1 WITH(UPDLOCK)
where NOT EXISTS ( select * from table1 where othervalue = @_othervalue )
select @_id = Id from table1 where othervalue = @_othervalue
Вопрос в том, как одновременно вставлять без дубликатов в SQL Server? Меня беспокоит тот факт, что я должен использовать ТОП, чтобы вставить только один раз.
Ответы:
Вы можете использовать оператор слияния с
serializable
подсказкой.источник
insert ... where not exist ...
шаблон и обнаружил, что вы можете получить взаимоблокировки и нарушения ключа, поэтому там было необходимо использовать Updlock и сериализуемые. Затем я протестировал оператор слияния и подумал, что он будет обрабатывать вещи немного лучше, и он сделал это потому, что там, где нет тупиков, но мне все еще приходилось использовать сериализуемый код, чтобы не было нарушений ключа.Если вам не нужны дубликаты в столбце «othervalue», вы можете сделать это, создав в
unique constraint
этом столбце. Запрос будет:Это выдаст ошибку, если запрос попытается вставить повторяющееся значение в столбец «другое значение».
источник
Используйте уникальное ограничение, которое рекомендует @StanleyJohns. Затем используйте BEGIN TRY END TRY вокруг вашего оператора вставки.
источник