Creo que estás tratando de resolver el problema de manera incorrecta. Lo que desea es la máxima protección de la coherencia de la base de datos. Si dos personas ejecutan un procedimiento almacenado al mismo tiempo, se puede violar la coherencia de la base de datos.
Para protegerse contra varios tipos de inconsistencias de la base de datos, el estándar SQL tiene cuatro niveles de aislamiento de transacciones:
- LEA SIN COMPROMISO donde básicamente las transacciones pierden su valor, otras transacciones ven datos sucios. ¡No uses esto!
- LEA COMPROMETIDO donde las transacciones solo ven datos confirmados, pero puede haber inconsistencias en las que dos transacciones pueden pasar por encima de los pies del otro
- LECTURA REPETIBLE donde se resuelve un tipo de inconsistencia, lectura no repetible
- SERIALIZABLE que garantiza que existe algún orden virtual en el que la ejecución de las transacciones conduciría a los resultados que su ejecución resultó en
Sin embargo, el estándar SQL tiene un enfoque basado en el bloqueo para estas inconsistencias de la base de datos, y por razones de rendimiento, muchas bases de datos adoptan un enfoque basado en el aislamiento de instantáneas que básicamente tiene estos niveles:
- LEA COMPROMETIDO, que es el mismo que está en el bloqueo de bases de datos basadas
- INSTANTÁNEA DE AISLAMIENTO donde la base de datos ve una instantánea de todos los datos y si intenta actualizar una fila que ha sido actualizada por alguna otra transacción, se cancela, pero hay algunas anomalías bien conocidas que pueden tener lugar
- SERIALIZABLE, que es lo mismo que en el bloqueo de bases de datos basadas, pero esta vez implementado de una manera diferente, no mediante bloqueos sino asegurando que no haya violaciones de serialización, y si se detecta dicha violación, cancelando una transacción
Las cancelaciones de transacciones en estas bases de datos basadas en el aislamiento de instantáneas pueden parecer preocupantes, pero una vez más, cada base de datos cancelará una transacción debido a un punto muerto, por lo que cualquier aplicación razonable necesita de todos modos poder volver a intentar una transacción.
Lo que desea es el nivel de aislamiento SERIALIZABLE : asegura que si las transacciones ejecutadas independientemente una tras otra dan como resultado un buen estado, cualquier ejecución paralela de las transacciones también resulta en un buen estado. Afortunadamente, Michael Cahill descubrió en su disertación doctoral cómo el nivel de aislamiento SERIALIZABLE puede ser soportado por bases de datos aisladas instantáneas con poco esfuerzo.
Si utiliza un nivel de aislamiento SERIALIZABLE en una base de datos aislada de instantánea, si dos personas intentan ejecutar el procedimiento almacenado al mismo tiempo y se pisarían los pies, la transacción se cancelaría.
Ahora, ¿SQL Server admite realmente el nivel de aislamiento SERIALIZABLE (en lugar de enmascarar el aislamiento de la instantánea detrás de la palabra clave SERIALIZABLE )? Francamente, no lo sé: la única base de datos que sé que lo admite es PostgreSQL.
Aunque no pude dar consejos específicos de SQL Server, todavía estoy publicando esta respuesta, ya que los usuarios de PostgreSQL y los usuarios de otras bases de datos que pueden considerar cambiar a PostgreSQL pueden beneficiarse de mi respuesta. Además, los usuarios de bases de datos que no son de PostgreSQL que no pueden cambiar a PostgreSQL pueden presionar a su proveedor de bases de datos favorito para que ofrezca un nivel de aislamiento SERIALIZABLE genuino .