Cómo manejar de manera efectiva las inserciones de llave duplicadas sin arrojar una excepción
-
29-10-2019 - |
Pregunta
Mi escenario de caso pasa el parámetro a un procedimiento, que solo hace un inserto. Pero dos hilos pueden intentar pasar el mismo valor.
¿Cómo manejar esta situación sin lanzar una excepción y con menos cantidad de cerraduras?
Mi requisito de rendimiento es de al menos 10k inserciones por segundo.
EDITAR: La columna es única. La marca de tiempo puede alterarse (ajustar) antes de la inserción.
Solución
Crear índice en la tabla con la opción de tecla Duplicada Ignore. No insertará la fila duplicada y tampoco lo hará ningún error.
P.ej
create unique index i1 on #tmp(id) with ignore_dup_key
insert into #tmp values(1,"A")
2> go
(1 row affected)
1> insert into #tmp values(1,"A")
2> go
Duplicate key was ignored.
(0 rows affected)
Otros consejos
Prueba el UNIR declaración
De msdn. Un escenario común es actualizar una o más columnas en una tabla si existe una fila coincidente, o insertar los datos como una nueva fila si no existe una fila coincidente. Esto generalmente se hace pasando parámetros a un procedimiento almacenado que contiene las declaraciones de actualización e inserción apropiadas. Con la declaración de fusión, puede realizar ambas tareas en una sola declaración.
Con respecto a sus preocupaciones de rendimiento, también hay una página en Optimización del rendimiento de la declaración de fusión
Como @Martin Smith ha señalado que hay una buena solución, aunque es contrario a mi pregunta, tiene un buen razonamiento detrás de lo que parece muy compatible. La respuesta original que puedes encontrar aquí publicado por @GBN.
BEGIN TRY
INSERT etc
END TRY
BEGIN CATCH
IF ERROR_NUMBER() <> 2627
RAISERROR etc
END CATCH
En serio, esto es más rápido y el más concurrente sin cerraduras, especialmente a altos volúmenes. ¿Qué pasa si el Updlock está escalado y toda la mesa está bloqueada?
El texto original de Paul Nielsen que puedes encontrar aquí. - lección 4.
Si alguien tiene un problema similar al mío, es bueno echarle un vistazo.