Je suis récemment tombé sur une situation plutôt frustrante où SQL Server refuse d'émettre des verrous uniquement contre une clé primaire lorsqu'une instruction comme celle-ci select * from table with (rowlock updlock) where key=value
est exécutée à son encontre. Maintenant, ne vous méprenez pas ici, ça bloque la ligne mais ça va un peu plus loin et verrouille la table aussi. J'ai lu à propos de l'escalade de verrouillage SQL et j'ai regardé l'utilisation d'index spécifiques dans les indicateurs de verrouillage, mais vous voyez, ce n'est pas pratique quand il y a de nombreux index dans une table avec des millions d'enregistrements et mises à jour qui doivent se produire sur ces enregistrements. Pour une petite table et une requête spécifique, il est possible d'obtenir le comportement désiré, mais lorsque la table a une grande largeur (plusieurs colonnes) et que de nombreux processus utilisent les données, cette méthode disparaît et peut devenir un véritable point de désaccord.Quels changements devraient être apportés à l'architecture de verrouillage de SQL Server pour le rendre plus convivial pour les développeurs?
Ce que je voudrais voir ajouter est une nouvelle lockhint sucent comme PKLock (qui se PRIMAIRES Key Lock) qui délivre un verrou contre la clé primaire d'une ligne et à tout moment un index, une scan de table ou autre méthode est utilisée pour obtenir la ligne, il vérifie ce verrou et l'honore au lieu de verrouiller la table entière.
En tant que tel verrou de table aurait pas besoin d'être émis et cela augmenterait considérablement la capacité d'exécution en parallèle du code par rapport à la DB.
S'il vous plaît peser sur cette idée et signaler les défauts qu'il pourrait avoir, les moyens qu'il pourrait être amélioré ou d'autres éléments qui devraient être ajoutés pour résoudre mon dilemme.
EDIT
@Remus
Si j'exécute cette requête
begin transaction
select lockname from locks where lockname='A'
update Locks Set locked=1 where lockname='A'
puis cette requête:
begin transaction
select lockname from locks where lockname='A'
ligne A est retourné dans les deux exemples avant de commettre les transactions. C'est lire derrière la mise à jour, pas de blocage.
Une solution réussie devrait faire ce qui suit sans spécifier les index à utiliser:
- avec Query 1: Lire et verrouiller A, mettre à jour un
- Avec Requête 2: Lire et verrouiller B, mise à jour B, Commit requête 2
- avec Query 2: Lire B et être bloqué jusqu'à son blocage sur A sont libérés
- avec Query 1: Engagez requête 1
- Avec requête 2: Lire et verrouiller A, mettre à jour A, Engagez requête 2
Ne devriez-vous pas suggérer cela à Microsoft au lieu d'ici? –
Je pense que Microsoft prendrait mieux note de cela s'il venait de la communauté. D'ailleurs c'est peut-être une mauvaise idée et si oui, j'aimerais savoir pourquoi et ce qui pourrait être fait différemment pour résoudre ce problème. – Middletone
donc votre déclaration exacte: 'select * de la table avec (rowlock updlock) où key = value' verrouille toute la grande table? ou votre requête est-elle plus complexe et êtes-vous sûr que la table entière est verrouillée? –