Mam problemy z współbieżnością z moimi wstawkami w procedurze przechowywanej. Odpowiednia część procedury jest następująca:
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
Kiedy uruchamiamy 3 lub 4 z tych przechowywanych proc jednocześnie, otrzymujemy od czasu do czasu wiele wstawek.
Planuję to naprawić tak:
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
Pytanie brzmi, czy to jak wstawiać jednocześnie bez duplikatów na serwerze SQL? Niepokoi mnie fakt, że muszę używać TOP, aby wstawić tylko raz.
Odpowiedzi:
Możesz użyć instrukcji scalania z
serializable
podpowiedziami.źródło
insert ... where not exist ...
wzorzec i odkryłem, że można uzyskać zakleszczenia i kluczowe naruszenia, więc konieczne było użycie aktualizacji i szeregowania. Następnie przetestowałem instrukcję scalenia i pomyślałem, że poradzi sobie ona trochę lepiej i zrobiło to, ponieważ tam nie było żadnych zakleszczeń, ale nadal musiałem używać serializowania, aby nie mieć kluczowych naruszeń.Jeśli nie chcesz duplikatów w kolumnie „inna wartość”, możesz to zrobić, tworząc
unique constraint
kolumnę w tej kolumnie. Zapytanie byłoby:Spowoduje to zwrócenie błędu, jeśli zapytanie spróbuje wstawić zduplikowaną wartość w kolumnie „inna wartość”.
źródło
Użyj unikalnego ograniczenia, takiego jak zalecane przez @StanleyJohns. Następnie użyj BEGIN TRY END TRY wokół instrukcji insert.
źródło