In jouw scenario zou ik aanraden om het isolatieniveau expliciet in te stellen op snapshot - dat voorkomt dat lezen in de weg staat van schrijven (inserts en updates) door vergrendelingen te voorkomen, maar die gelezen zouden nog steeds "goede" reads zijn (d.w.z. geen vuile gegevens - het is niet hetzelfde als een NOLOCK)
Over het algemeen merk ik dat wanneer ik vergrendelingsproblemen heb met mijn vragen, ik handmatig de toegepaste vergrendeling beheer. bijv. ik zou updates doen met vergrendelingen op rijniveau om vergrendeling op pagina-/tabelniveau te voorkomen, en mijn leeswaarden instellen op readpast (accepterend dat ik sommige gegevens misschien mis, in sommige scenario's is dat mogelijk)link|edit|delete|flag
EDIT-- Alle opmerkingen combineren in het antwoord
Als onderdeel van het optimalisatieproces vermijdt de sql-server dat er vastleggingen worden gedaan op een pagina waarvan hij weet dat deze niet is gewijzigd, en valt hij automatisch terug op een mindere sluitstrategie. In jouw geval zakt de sql-server van een serialiseerbare read naar een herhaalbare read.
Vraag:Bedankt voor die nuttige informatie over het verlagen van isolatieniveaus. Kun je een reden bedenken waarom het Serializable IsolationLevel in de eerste plaats zou gebruiken, aangezien we geen expliciete transactie gebruiken voor de SELECT - we hadden begrepen dat de impliciete transactie ReadCommitted zou gebruiken?
A:SQL Server zal standaard Read Commmited gebruiken als dat uw standaard isolatieniveau is MAAR als u geen extra vergrendelingsstrategie opgeeft in uw query, zegt u in feite tegen sql-server "doe wat u denkt dat het beste is, maar mijn voorkeur is Read Committed". Aangezien SQL Server vrij is om te kiezen, is dat ook zo om de query te optimaliseren. (Het optimalisatie-algoritme in de sql-server is erg complex en ik begrijp het zelf niet helemaal). Het niet expliciet uitvoeren binnen een transactie heeft geen invloed op het isolatieniveau dat de sql-server gebruikt.
V:Een laatste ding, lijkt het redelijk dat SQL Server het isolatieniveau (en vermoedelijk het aantal benodigde vergrendelingen) zou verhogen om de query te optimaliseren? Ik vraag me ook af of het hergebruik van een gepoolde verbinding hier invloed op zou hebben als deze het laatst gebruikte isolatieniveau zou overnemen?
A:Sql-server zal dat doen als onderdeel van een proces genaamd "Lock Escalation". Van http://support.microsoft.com/kb/323630 , ik citeer:"Microsoft SQL Server bepaalt dynamisch wanneer vergrendelings-escalatie moet worden uitgevoerd. Bij het nemen van deze beslissing houdt SQL Server rekening met het aantal vergrendelingen dat op een bepaalde scan wordt vastgehouden, het aantal vergrendelingen dat door de hele transactie wordt vastgehouden, en het geheugen dat wordt gebruikt voor vergrendelingen in het systeem als geheel. Doorgaans resulteert het standaardgedrag van SQL Server in escalatie van vergrendelingen die alleen plaatsvinden op die punten waar dit de prestaties zou verbeteren of wanneer u buitensporig systeemvergrendelingsgeheugen moet terugbrengen tot een redelijker niveau . Sommige ontwerpen van applicaties of query's kunnen echter leiden tot escalatie van vergrendelingen op een moment dat dit niet wenselijk is, en de geëscaleerde tabelvergrendeling kan andere gebruikers blokkeren".
Hoewel lock-escalatie niet precies hetzelfde is als het wijzigen van het isolatieniveau waarop een query wordt uitgevoerd, verbaast dit me omdat ik niet had verwacht dat de sql-server meer sloten zou gebruiken dan wat het standaardisolatieniveau toestaat.