Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Änderungen der Standardisolationsstufe von SQL Server

In Ihrem Szenario würde ich empfehlen, die Isolationsstufe explizit auf Snapshot festzulegen. Dadurch wird verhindert, dass Lesevorgänge Schreibvorgängen (Einfügungen und Aktualisierungen) im Wege stehen, indem Sperren verhindert werden. Diese Lesevorgänge wären jedoch immer noch "gute" Lesevorgänge (dh keine schmutzigen Daten). es ist nicht dasselbe wie ein NOLOCK)

Im Allgemeinen stelle ich fest, dass ich bei Sperrproblemen mit meinen Abfragen die angewendete Sperre manuell steuere. z.B. Ich würde Aktualisierungen mit Sperren auf Zeilenebene vornehmen, um Sperren auf Seiten-/Tabellenebene zu vermeiden, und meine Lesevorgänge auf readpast setzen (wobei ich akzeptiere, dass ich einige Daten vermissen könnte, in einigen Szenarien könnte dies in Ordnung sein)link|edit|delete|flag

BEARBEITEN - Kombinieren aller Kommentare in der Antwort

Als Teil des Optimierungsprozesses vermeidet SQL Server festgeschriebene Lesevorgänge auf einer Seite, von der er weiß, dass sie sich nicht geändert hat, und greift automatisch auf eine geringere Sperrstrategie zurück. In Ihrem Fall fällt SQL Server von einem serialisierbaren Lesevorgang auf einen wiederholbaren Lesevorgang.

F:Danke für diese nützliche Information bezüglich des Absenkens von Isolationsstufen. Können Sie sich einen Grund vorstellen, warum es überhaupt Serializable IsolationLevel verwenden würde, da wir keine explizite Transaktion für SELECT verwenden - es war unser Verständnis, dass die implizite Transaktion ReadCommitted verwenden würde?

A:Standardmäßig verwendet SQL Server Read Commited, wenn dies Ihre Standard-Isolationsstufe ist, ABER wenn Sie in Ihrer Abfrage keine zusätzliche Sperrstrategie angeben, sagen Sie im Grunde zu SQL Server:"Tun Sie, was Sie für das Beste halten, aber meine Präferenz ist Read Commited". Da SQL Server frei wählen kann, tut er dies, um die Abfrage zu optimieren. (Der Optimierungsalgorithmus in SQL Server ist sehr komplex und ich verstehe ihn selbst nicht vollständig). Nicht ausdrücklich innerhalb einer Transaktion ausgeführt zu werden, beeinflusst afaik nicht die Isolationsstufe, die der SQL-Server verwendet.

F:Eine letzte Sache, erscheint es vernünftig, dass SQL Server die Isolationsstufe (und vermutlich die Anzahl der erforderlichen Sperren) erhöht, um die Abfrage zu optimieren? Ich frage mich auch, ob die Wiederverwendung einer gepoolten Verbindung dies beeinflussen würde, wenn sie die zuletzt verwendete Isolationsstufe erben würde?

A:SQL-Server wird dies als Teil eines Prozesses namens „Lock Escalation“ tun. Von http://support.microsoft.com/kb/323630 , ich zitiere:"Microsoft SQL Server bestimmt dynamisch, wann eine Sperreneskalation durchgeführt werden soll. Bei dieser Entscheidung berücksichtigt SQL Server die Anzahl der Sperren, die bei einem bestimmten Scan gehalten werden, die Anzahl der Sperren, die von der gesamten Transaktion gehalten werden, und der Arbeitsspeicher, der für Sperren im System als Ganzes verwendet wird.Normalerweise führt das Standardverhalten von SQL Server dazu, dass eine Sperrenausweitung nur an den Punkten auftritt, an denen die Leistung verbessert werden würde oder wenn Sie übermäßigen Systemsperrspeicher auf ein vernünftigeres Maß reduzieren müssen . Einige Anwendungs- oder Abfragedesigns können jedoch eine Sperreneskalation zu einem Zeitpunkt auslösen, zu dem dies nicht erwünscht ist, und die eskalierte Tabellensperre kann andere Benutzer blockieren.“

Obwohl die Sperrenausweitung nicht genau dasselbe ist wie das Ändern der Isolationsstufe, unter der eine Abfrage ausgeführt wird, überrascht mich das, weil ich nicht erwartet hätte, dass der SQL-Server mehr Sperren nimmt, als die Standard-Isolationsstufe zulässt.