Puede usar los BLOQUEOS para hacer cosas SERIALIZABLES, pero esto reduce la simultaneidad. ¿Por qué no probar primero la condición común ("principalmente insertar o seleccionar en su mayoría") seguido de un manejo seguro de la acción "remedial"? Es decir, el patrón "JFDI" ...
Parcialmente inserciones esperadas (estadio de béisbol 70-80% +):
Sólo trate de insertar. Si falla, la fila ya se ha creado. No necesita preocuparse por la concurrencia porque TRY/CATCH se ocupa de los duplicados por usted.
BEGIN TRY
INSERT Table VALUES (@Value)
SELECT @id = SCOPEIDENTITY()
END TRY
BEGIN CATCH
IF ERROR_NUMBER() <> 2627
RAISERROR etc
ELSE -- only error was a dupe insert so must already have a row to select
SELECT @id = RowID FROM Table WHERE RowValue = @VALUE
END CATCH
Parcialmente seleccionados:
similares, pero trata de obtener datos de primera. Sin datos = INSERT es necesario. Nuevamente, si 2 llamadas simultáneas intentan INSERTAR porque ambas encontraron la fila que faltaba en los controles TRY/CATCH.
BEGIN TRY
SELECT @id = RowID FROM Table WHERE RowValue = @VALUE
IF @@ROWCOUNT = 0
BEGIN
INSERT Table VALUES (@Value)
SELECT @id = SCOPEIDENTITY()
END
END TRY
BEGIN CATCH
IF ERROR_NUMBER() <> 2627
RAISERROR etc
ELSE
SELECT @id = RowID FROM Table WHERE RowValue = @VALUE
END CATCH
La segunda parece repetirse, pero es muy concurrente. Cerraduras lograrían el mismo, pero a expensas de concurrencia ...
Editar:
Por qué no utilizar la combinación de ...
si se utiliza la cláusula OUTPUT lo hará solamente retorno lo que está actualizado Por lo tanto, necesita una ACTUALIZACIÓN ficticia para generar la tabla INSERTED para la cláusula OUTPUT. Si tiene que hacer actualizaciones ficticias con muchas llamadas (como lo implica OP) es una gran cantidad de logs de registro solo para poder usar MERGE.
Esto es similar a: http://stackoverflow.com/questions/13540/insert-update-stored-proc-on-sql-server/193876#193876 –
Estoy de acuerdo, es similar, pero yo diría que la diferencia es que no hay necesidad de una actualización, solo una instrucción de inserción o selección.En su respuesta, usa SERIALIZABLE como una sugerencia conjunta. ¿Sería esa tu recomendación para la consulta anterior en la declaración SELECT? – 8kb
Yerp una inserción con la pista serializable, potencialmente en una transacción debería hacer el truco. Puedo intentar escribir una respuesta, pero este iPad me hace sonar descarado :( –