Je n'aborderai pas le READ UNCOMMITTED argument, juste votre question initiale.
Oui, vous avez besoin WITH(NOLOCK)sur chaque table de la jointure. Non, vos requêtes ne sont pas les mêmes.
Essayez cet exercice. Commencez une transaction et insérez une ligne dans table1 et table2. Ne pas valider ou annuler la transaction pour le moment. À ce stade, votre première requête retournera avec succès et inclura les lignes non validées; votre deuxième requête ne retournera pas car table2 n'a pas d' WITH(NOLOCK)indice dessus.
J'étais presque sûr que vous devez spécifier le NOLOCKpour chacun JOINdans la requête. Mais mon expérience s'est limitée à SQL Server 2005.
Quand j'ai recherché MSDN juste pour confirmer, je n'ai rien trouvé de définitif. Les déclarations ci-dessous semblent me faire penser que pour 2008, vos deux déclarations ci-dessus sont équivalentes, bien que ce ne soit pas le cas pour 2005:
[SQL Server 2008 R2]
Toutes les indications de verrouillage sont propagées à toutes les tables et vues auxquelles le plan de requête accède , y compris les tables et vues référencées dans une vue. En outre, SQL Server effectue les vérifications de cohérence de verrouillage correspondantes.
[SQL Server 2005]
Dans SQL Server 2005, toutes les indications de verrouillage sont propagées à toutes les tables et vues référencées dans une vue. En outre, SQL Server effectue les vérifications de cohérence de verrouillage correspondantes.
De plus, veuillez noter - et cela s'applique à la fois à 2005 et à 2008:
Les indications de table sont ignorées si la table n'est pas accédée par le plan de requête. Cela peut être dû au fait que l'optimiseur a choisi de ne pas accéder du tout à la table, ou parce qu'une vue indexée est accédée à la place. Dans ce dernier cas, l'accès à une vue indexée peut être empêché en utilisant l' OPTION (EXPAND VIEWS)indicateur de requête.
@In Sane: Intéressant ... merci pour ça ... Je suppose que je ne fais pas de mal en l'incluant sur JOINS, même si ce n'est pas entièrement nécessaire? La documentation sur NOLOCK est assez rare comme vous l'avez mentionné; J'ai eu du mal à trouver moi-même quoi que ce soit de concluant.
DanP
2
@InSane: D'où avez-vous obtenu ces informations? Cela semble aller à l'encontre de la réponse acceptée.
Le texte de 2005 parle de VIEWS. Donc, si vous faites "from myview with (nolock)", cela indique que le nolock est propagé à toutes les tables et vues impliquées dans myview (vous pourriez avoir 10 jointures là-dedans). Je ne sais pas ce que signifie exactement le texte de 2008 car il ajoute «accessible par le plan de requête» en plus des vues.
Thierry_S
9
Ni. Vous définissez le niveau d'isolement READ UNCOMMITTEDauquel il est toujours préférable de donner des conseils de verrouillage individuels. Ou, mieux encore, si vous vous souciez de détails tels que la cohérence , utilisez l' isolement de snapshot .
@Remus: Je ne suis pas sûr de pouvoir utiliser READ UNCOMMITTED dans mon cas car j'accède à la connexion via NHibernate pour effectuer un appel ADO.NET brut spécial; cela peut-il être spécifié en ligne dans la requête, ou obéira-t-il au niveau de transaction présent sur la transaction NHibernate?
DanP
Enveloppez l'appel using (TransactionScope scope=new TransactionScope(..., TransactionOptions) {...}et définissez les IsolationLeveloptions: msdn.microsoft.com/en-us/library
Remus Rusanu
@Remus: Malheureusement, la gestion des transactions est prise en charge à un niveau beaucoup plus élevé que cela, donc ce n'est pas non plus une option.
DanP
Je vois. Ensuite, pour répondre à votre question: NOLOCK est un indice de table , et en tant que tel, il s'applique à l'ensemble de lignes auquel est ajouté (table, vue, TVF, etc.). Si plusieurs ensembles de lignes sont joints dans une requête, chacun aura besoin de son propre indice NOLOCK.
Remus Rusanu
2
Mais avez-vous envisagé l'isolement des instantanés? ALTER DATABASE ... SET READ_COMMITTED_SNAPSHOT ON;. Les résultats sont spectaculaires, car toutes les lectures validées normales se transforment en lectures instantanées, sans verrouillage mais cohérentes. Le coût est une tempdbcharge accrue : msdn.microsoft.com/en-us/library/ms175492.aspx
Ni. Vous définissez le niveau d'isolement
READ UNCOMMITTED
auquel il est toujours préférable de donner des conseils de verrouillage individuels. Ou, mieux encore, si vous vous souciez de détails tels que la cohérence , utilisez l' isolement de snapshot .la source
using (TransactionScope scope=new TransactionScope(..., TransactionOptions) {...}
et définissez lesIsolationLevel
options: msdn.microsoft.com/en-us/libraryALTER DATABASE ... SET READ_COMMITTED_SNAPSHOT ON;
. Les résultats sont spectaculaires, car toutes les lectures validées normales se transforment en lectures instantanées, sans verrouillage mais cohérentes. Le coût est unetempdb
charge accrue : msdn.microsoft.com/en-us/library/ms175492.aspx