Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Modifications du niveau d'isolation SQL Server par défaut

Dans votre scénario, je recommanderais de définir explicitement le niveau d'isolement sur l'instantané - cela empêchera la lecture de gêner les écritures (insertions et mises à jour) en empêchant les verrous, mais ceux lus seraient toujours de "bonnes" lectures (c'est-à-dire pas des données sales - ce n'est pas la même chose qu'un NOLOCK)

Généralement, je trouve que là où j'ai des problèmes de verrouillage avec mes requêtes, je contrôle manuellement le verrou appliqué. par exemple. je ferais des mises à jour avec des verrous au niveau de la ligne pour éviter le verrouillage au niveau de la page/table, et définirais mes lectures sur readpast (en acceptant que je puisse manquer certaines données, dans certains scénarios, cela pourrait être correct)link|edit|delete|flag

EDIT-- Combiner tous les commentaires dans la réponse

Dans le cadre du processus d'optimisation, le serveur sql évite d'obtenir des lectures validées sur une page dont il sait qu'elle n'a pas changé, et revient automatiquement à une stratégie de verrouillage moindre. Dans votre cas, le serveur sql passe d'une lecture sérialisable à une lecture reproductible.

Q :Merci pour ces informations utiles concernant la suppression des niveaux d'isolement. Pouvez-vous penser à une raison pour laquelle il utiliserait Serializable IsolationLevel en premier lieu, étant donné que nous n'utilisons pas de transaction explicite pour le SELECT - nous avions compris que la transaction implicite utiliserait ReadCommitted ?

R :Par défaut, SQL Server utilisera Read Commmited s'il s'agit de votre niveau d'isolement par défaut MAIS si vous ne spécifiez pas en plus une stratégie de verrouillage dans votre requête, vous dites essentiellement au serveur sql "faites ce que vous pensez être le mieux, mais ma préférence est en lecture validée". Étant donné que SQL Server est libre de choisir, il le fait afin d'optimiser la requête. (L'algorithme d'optimisation dans sql server est très complexe et je ne le comprends pas parfaitement moi-même). Ne pas s'exécuter explicitement dans une transaction n'affecte pas, autant que je sache, le niveau d'isolement utilisé par le serveur sql.

Q :Une dernière chose, semble-t-il raisonnable que SQL Server augmente le niveau d'isolement (et vraisemblablement le nombre de verrous requis) pour optimiser la requête ? Je me demande également si la réutilisation d'une connexion groupée affecterait cela si elle héritait du dernier niveau d'isolement utilisé ?

R :Le serveur SQL le fera dans le cadre d'un processus appelé "Lock Escalation". Depuis http://support.microsoft.com/kb/323630 , je cite:"Microsoft SQL Server détermine dynamiquement quand effectuer une escalade de verrous. Lors de la prise de cette décision, SQL Server prend en compte le nombre de verrous détenus lors d'une analyse particulière, le nombre de verrous détenus par l'ensemble de la transaction, et la mémoire utilisée pour les verrous dans l'ensemble du système. En règle générale, le comportement par défaut de SQL Server entraîne une escalade des verrous uniquement aux points où cela améliorerait les performances ou lorsque vous devez réduire la mémoire de verrouillage système excessive à un niveau plus raisonnable . Cependant, certaines conceptions d'applications ou de requêtes peuvent déclencher une escalade de verrous à un moment où cela n'est pas souhaitable, et le verrou de table escaladé peut bloquer d'autres utilisateurs".

Bien que l'escalade des verrous ne soit pas exactement la même chose que la modification du niveau d'isolement sous lequel une requête s'exécute, cela me surprend car je ne m'attendrais pas à ce que le serveur SQL prenne plus de verrous que ce que le niveau d'isolement par défaut autorise.