Je pense que vous essayez de résoudre le problème d'une manière incorrecte. Ce que vous voulez, c'est une protection maximale de la cohérence de la base de données. Si deux personnes exécutent une procédure stockée en même temps, la cohérence de la base de données peut être violée.
Pour se protéger contre divers types d'incohérences de base de données, la norme SQL a quatre niveaux d'isolement des transactions:
- LIRE NON ENGAGÉ où les transactions perdent essentiellement de leur valeur, d'autres transactions voient des données sales. Ne l'utilisez pas!
- LIRE COMMIS lorsque les transactions ne voient que les données validées, mais il peut y avoir des incohérences lorsque deux transactions peuvent se chevaucher mutuellement
- REPEATABLE READ où un type d'incohérence, lecture non répétable, est résolu
- SERIALIZABLE qui garantit qu'il existe un certain ordre virtuel dans lequel l'exécution des transactions conduirait aux résultats que leur exécution a entraîné
Cependant, la norme SQL a une approche basée sur le verrouillage pour ces incohérences de base de données, et pour des raisons de performances, de nombreuses bases de données adoptent une approche basée sur l'isolement d'instantané qui a essentiellement ces niveaux:
- LIRE ENGAGÉ qui est le même que c'est dans le verrouillage des bases de données
- SNAPSHOT ISOLATION où la base de données voit un instantané de toutes les données et si elle essaie de mettre à jour une ligne qui a été mise à jour par une autre transaction, elle est annulée, mais il existe des anomalies bien connues qui peuvent avoir lieu
- SERIALIZABLE qui est le même que dans les bases de données de verrouillage, mais cette fois implémenté d'une manière différente, non pas en prenant des verrous mais en s'assurant qu'il n'y a pas de violation de sérialisation, et si une telle violation est détectée, l'annulation d'une transaction
Les annulations de transactions dans ces bases de données basées sur l'isolement d'instantané peuvent sembler inquiétantes, mais là encore, chaque base de données annulera une transaction en raison d'un blocage, de sorte que toute application raisonnable doit de toute façon être en mesure de réessayer une transaction.
Ce que vous voulez, c'est le niveau d'isolement SERIALISABLE : il garantit que si les transactions exécutées indépendamment les unes après les autres aboutissent à un bon état, toute exécution parallèle des transactions se traduit également par un bon état. Heureusement, Michael Cahill a découvert dans sa thèse de doctorat comment le niveau d'isolement SERIALISABLE peut être supporté par des bases de données instantanées isolées avec peu d'effort.
Si vous utilisez un niveau d'isolement SERIALIZABLE dans une base de données isolée par instantané, si deux personnes tentent d'exécuter la procédure stockée simultanément et qu'elles se mettent sur les pieds l'une de l'autre, l'une des transactions est annulée.
Désormais, SQL Server prend-il réellement en charge le niveau d'isolement SERIALIZABLE (au lieu de masquer l'isolement d'instantané derrière le mot clé SERIALIZABLE )? Franchement, je ne sais pas: la seule base de données que je connaisse qui le supporte est PostgreSQL.
Même si je n'ai pas donné de conseils spécifiques à SQL Server, je poste quand même cette réponse, car les utilisateurs de PostgreSQL et les utilisateurs d'autres bases de données qui peuvent envisager de passer à PostgreSQL peuvent bénéficier de ma réponse. De plus, les utilisateurs de bases de données non PostgreSQL qui ne peuvent pas passer à PostgreSQL peuvent faire pression sur leur fournisseur de base de données préféré pour offrir un véritable niveau d'isolement SERIALISABLE .