I dit scenarie vil jeg anbefale, at du udtrykkeligt indstiller isolationsniveauet til snapshot - det vil forhindre læsning i at komme i vejen for skrivninger (indsættelser og opdateringer) ved at forhindre låse, men de læste ville stadig være "gode" læsninger (dvs. ikke beskidte data - det er ikke det samme som en NOLOCK)
Generelt finder jeg ud af, at hvor jeg har låseproblemer med mine forespørgsler, kontrollerer jeg manuelt den anvendte lås. for eksempel. Jeg ville lave opdateringer med låse på rækkeniveau for at undgå låsning af side-/tabelniveauer, og sætte mine læsninger til readpast (accepterer, at jeg kan gå glip af nogle data, i nogle scenarier kan det være ok)link|edit|delete|flag
EDIT-- Kombinerer alle kommentarerne i svaret
Som en del af optimeringsprocessen undgår sql server at få commited reads på en side, som den ved ikke har ændret sig, og falder automatisk tilbage til en mindre låsestrategi. I dit tilfælde falder sql-serveren fra en serialiserbar læsning til en gentagelig læsning.
Spørgsmål:Tak for den nyttige information om at droppe isolationsniveauer. Kan du komme i tanke om nogen grund til, at det ville bruge Serializable IsolationLevel i første omgang, givet at vi ikke bruger en eksplicit transaktion til SELECT - det var vores forståelse, at den implicitte transaktion ville bruge ReadCommitted?
A:Som standard vil SQL Server bruge Read Committed, hvis det er dit standard isolationsniveau, MEN hvis du ikke yderligere angiver en låsestrategi i din forespørgsel, siger du grundlæggende til sql server "gør det, du synes er bedst, men min præference er læst engageret". Da SQL Server er frit at vælge, så gør den det for at optimere forespørgslen. (Optimeringsalgoritmen i sql server er meget kompleks, og jeg forstår det ikke helt selv). At ikke eksplicit udføres inden for en transaktion, påvirker naturligvis ikke det isolationsniveau, som sql-serveren bruger.
Spørgsmål:En sidste ting, virker det rimeligt, at SQL Server vil øge isolationsniveauet (og formentlig antallet af krævede låse) for at optimere forespørgslen? Jeg spekulerer også på, om genbrug af en samlet forbindelse ville påvirke dette, hvis den arvede det sidst brugte isolationsniveau?
A:SQL-serveren vil gøre det som en del af en proces kaldet "Lock Escalation". Fra http://support.microsoft.com/kb/323630 , jeg citerer:"Microsoft SQL Server bestemmer dynamisk, hvornår låseeskalering skal udføres. Når denne beslutning træffes, tager SQL Server højde for antallet af låse, der holdes på en bestemt scanning, antallet af låse, der holdes af hele transaktionen, og den hukommelse, der bruges til låse i systemet som helhed. Typisk resulterer SQL Servers standardadfærd i, at låseeskalering kun forekommer på de punkter, hvor det ville forbedre ydeevnen, eller når du skal reducere overdreven systemlåshukommelse til et mere rimeligt niveau . Nogle applikations- eller forespørgselsdesigns kan dog udløse låseskalering på et tidspunkt, hvor det ikke er ønskeligt, og den eskalerede tabellås kan blokere andre brugere".
Selvom låseeskalering ikke er præcis det samme som at ændre det isolationsniveau, en forespørgsel kører under, overrasker dette mig, fordi jeg ikke havde forventet, at sql-serveren ville tage flere låse, end hvad standardisolationsniveauet tillader.