J'ai des problèmes de concurrence avec mes insertions dans une procédure stockée. La partie pertinente de la procédure est la suivante:
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
Lorsque nous exécutons 3 ou 4 de ces proc stockés simultanément, nous obtenons plusieurs insertions à l'occasion.
Je prévois de résoudre ce problème comme ceci:
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
La question est, est-ce que comment insérer simultanément sans doublons dans le serveur SQL? Le fait que je doive utiliser TOP pour ne l'insérer qu'une seule fois me dérange.
Réponses:
Vous pouvez utiliser une instruction de fusion avec
serializable
indice.la source
insert ... where not exist ...
modèle et constaté que vous pouvez obtenir des blocages et des violations de clé, il était donc nécessaire d'utiliser le verrouillage de mise à jour et la sérialisation. J'ai ensuite testé la déclaration de fusion et j'ai pensé qu'elle gérerait les choses un peu mieux et c'est parce qu'il n'y avait pas de blocages mais que je devais encore utiliser sérialisable pour ne pas avoir de violations clés.Si vous ne voulez pas de doublons sur la colonne «autre valeur», vous pouvez le faire en créant un
unique constraint
sur cette colonne. La requête serait:Cela renverrait une erreur si une requête tentait d'insérer une valeur en double dans la colonne «autre valeur».
la source
Utilisez une contrainte unique comme le recommande @StanleyJohns. Utilisez ensuite BEGIN TRY END TRY autour de votre instruction d'insertion.
la source