Ich habe Parallelitätsprobleme mit meinen Einfügungen in einer gespeicherten Prozedur. Der relevante Teil des Verfahrens ist:
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
Wenn wir 3 oder 4 dieser gespeicherten Prozesse gleichzeitig ausführen, erhalten wir gelegentlich mehrere Einfügungen.
Ich plane dies wie folgt zu beheben:
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
Die Frage ist, ist das, wie man gleichzeitig ohne Duplikate in SQL Server einfügt? Die Tatsache, dass ich TOP nur zum einmaligen Einfügen verwenden muss, stört mich.
Antworten:
Sie können eine merge-Anweisung mit einem
serializable
Hinweis verwenden.quelle
insert ... where not exist ...
Muster getestet und festgestellt, dass Deadlocks und Schlüsselverletzungen auftreten können. Daher war es erforderlich, Updlock und serialisierbar zu verwenden. Ich habe dann die Merge-Anweisung getestet und dachte, sie würde die Dinge ein bisschen besser handhaben, und zwar, weil es keine Deadlocks gab, aber ich musste trotzdem serializable verwenden, um keine Schlüsselverletzungen zu haben.Wenn Sie keine Duplikate in der Spalte "othervalue" möchten, können Sie dies tun, indem Sie
unique constraint
in dieser Spalte eine erstellen . Die Abfrage wäre:Dies würde einen Fehler auslösen, wenn eine Abfrage versucht, einen doppelten Wert in die Spalte "othervalue" einzufügen.
quelle
Verwenden Sie eine eindeutige Einschränkung, wie von @StanleyJohns empfohlen. Verwenden Sie dann BEGIN TRY END TRY um Ihre Einfügeanweisung.
quelle