Isolationsstufe in der Sql-Transaktion

7

Ich habe SqlTransaction in c # implementiert, um die Transaktion zu starten, zu committen und zurückzusetzen. Alles läuft gut, aber ich habe ein Problem beim Zugriff auf die Tabellen, die während der Transaktion verbunden sind. Ich konnte die Tabelle während der Transaktion nicht lesen (diese Tabelle befindet sich in der Transaktion). Bei der Suche habe ich festgestellt, dass dies aufgrund einer exklusiven Sperre geschieht. Alle nachfolgenden Auswahlvorgänge für diese Daten müssen wiederum darauf warten, dass die exklusive Sperre aufgehoben wird. Dann habe ich jede Isolationsstufe von SqlTransaction durchlaufen, aber es hat nicht funktioniert. Daher muss ich die exklusive Sperre während der Transaktion freigeben, damit andere Benutzer Zugriff auf diese Tabelle haben und die Daten lesen können. Gibt es eine Methode, dies zu erreichen? Vielen Dank im Voraus.

Hier ist mein c # -Code für die Transaktion

%Vor%

Dieser Code funktioniert einwandfrei, aber das Problem besteht darin, dass ich während der Transaktion auf die Daten von Tabellen (die während der Transaktion zugegriffen werden) zugreifen kann. Auf die Tabellen wird von anderen Teilen der Anwendung zugegriffen. Also, als ich versuchte, Daten aus der Tabelle zu lesen, löst es eine Ausnahme aus.

    
The Bearded Llama 29.02.2012, 08:33
quelle

4 Antworten

14

Eine SQL-Transaktion ist standardmäßig ACID. Insbesondere ist es das "Ich", das dich hier verletzt - das ist entworfen um zu verhindern, dass andere Verbindungen den inkonsistenten Zwischenzustand sehen.

Eine einzelne Leseverbindung kann diese Regel ignorieren, indem sie den NOLOCK -Hinweis oder die READ UNCOMMITTED -Isolationsstufe verwendet, aber es klingt wie gewünscht, dass die schreibende Verbindung nicht akzeptiert wird Schlösser. Nun, das wird nicht passieren.

Was jedoch helfen könnte, ist, dass die Leser die Snapshot Isolation verwenden, wodurch eine Isolation erreicht wird, ohne dass der Leser Sperren nimmt (indem er, wie der Name schon sagt, einen Punkt betrachtet) -in-time-Shapshot des konsistenten Status, als die Transaktion gestartet wurde.

Allerdings sollten Sie IMO besser einen Blick darauf werfen:

  • mehrere, detailliertere Transaktionen vom Verfasser
  • Ausführen der Arbeit in einer Zwischenspeichertabelle (eine parallele Kopie der Daten), dann Zusammenführen dieser Daten in die realen -Daten in einigen Masseneinfügungs- / Aktualisierungs- / Löschoperationen, Minimieren der Transaktionszeit

Der erste ist einfacher.

Die einfache Tatsache ist: Wenn Sie eine lang andauernde Transaktion ausführen, die mit vielen Daten arbeitet, yes , werden Sie Probleme verursachen. Deshalb tu das nicht . Das System funktioniert ordnungsgemäß.

    
Marc Gravell 29.02.2012, 09:05
quelle
3

Versuchen Sie auch, Ihre Lesevorgänge innerhalb einer Transaktion auszuführen, und verwenden Sie die Isolationsstufe READ UNCOMMITTED . Dadurch wird verhindert, dass der Lesevorgang gesperrt wird. Dies kann jedoch zu ungültigen Ergebnissen führen:

%Vor%

Es gibt ein Missverständnis, dass der Umgang mit Transaktionen / Isolationsstufen nur beim Schreiben eine Rolle spielt, obwohl es beim Lesen genauso wichtig ist.

    
ntziolis 29.02.2012 08:43
quelle
2

Das Problem liegt nicht auf der Ebene des Schreibens in die Datenbank, sondern auf der Ebene der Lesewerte. Sie versuchen, Werte einzufügen, die eingefügt werden. Versuchen Sie, Ihre Select-Abfrage zu ändern:

%Vor%

jedoch überschreibt dieser die Isolationsstufe der aktuellen Transaktion und kann unsaubere Lesevorgänge verursachen.

Die Frage ist also: Wenn Sie die Transaktion für alle Abfragen verwenden oder nur einfügen / aktualisieren?

    
Marcin 29.02.2012 08:59
quelle
1

@ AKASH88, SNAPSHOT Isolationsstufe ist, was Sie suchen.

Du sagst, dass es sogar mit SNAPSHOT nicht wie erwartet funktioniert, exklusive Sperre passiert, ich kann das verstehen, ich hatte das gleiche Problem.

Stellen Sie sicher, dass Sie SNAPSHOT nicht nur für die Datenbankoptionen aktivieren, sondern auch READ COMMITTED SNAPSHOT aktiviert sein muss.

Dies ist SQL Server 2008. Daher ist es immer noch unsicher, ob diese Antwort helfen wird: (

Beste Grüße!

    
Agustin Garzon 07.02.2014 19:31
quelle