2008-10-21 3 views
6

Betrachten Sie das folgende SQL:Wie groß ist der Isolationsumfang in geschachtelten Transaktionen in SQL Server?

 
BEGIN TRAN 
SET TRANSACTION ISOLATION LEVEL READ COMMITTED 

INSERT Bands 
    ( Name ) 
SELECT 'Depeche Mode' 
UNION 
SELECT 'Arcade Fire' 

    -- I've indented the inner transaction to make it clearer. 

    BEGIN TRAN 
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 

    SELECT * 
     FROM Bands 

    COMMIT 

-- What is the isolation level right here? 

UPDATE Bands 
    SET Name = 'Modest Mouse' 
WHERE Name = 'Oddest House' 

COMMIT 

Insgesamt starten wir eine Transaktion und stellen Sie die Isolationsstufe auf READ COMMITTED. Wir führen dann ein zufälliges SQL aus und starten eine andere verschachtelte Transaktion. In dieser Transaktion ändern wir die Isolationsstufe in READ UNCOMMITTED. Wir begehen diese Transaktion und kehren zum anderen zurück.

Nun, meine Vermutung ist, dass nach dem inneren Festschreiben die Isolationsstufe zu READ COMMITTED zurückkehrt. Ist das richtig?

Antwort

7

Ich glaube nicht, dass das richtig ist.

Siehe die Bemerkungen hier: Set Transaction

Nur einer der Isolationsstufe Optionen zu einem Zeitpunkt festgelegt werden kann, und es bleibt gesetzt, für diese Verbindung bis explizit geändert wird.

+0

das ist korrekt Ich habe gerade mit sp_lock getestet –

7

Sie [Bob Probst] sind korrekt. Interessanterweise nach den documentation Sie verknüpft:

Wenn Sie TRANSACTION ISOLATION LEVEL in einer Stored Procedure oder Trigger-SET Ausgabe, wenn das Objekt kehrt die Isolationsstufe auf das Niveau in der Tat zurückgesetzt steuern ist, wenn das Objekt aufgerufen wurde. Wenn Sie beispielsweise REPEATABLE READ in einem Stapel setzen und der Stapel dann eine gespeicherte Prozedur aufruft, die die Isolationsstufe auf SERIALIZABLE setzt, wird die Einstellung der Isolationsstufe auf REPEATABLE READ zurückgesetzt, wenn die gespeicherte Prozedur die Steuerung an den Stapel zurückgibt.

So, hier ist das Endergebnis, dass SET TRANSACTION ISOLATION LEVEL hat Verfahren Affinität, nicht Transaktion Affinität (wie ich gedacht hatte).

Super!

+2

Nun, das ist zum Kotzen, lol! Meine C# -Datenbank-API akzeptiert offene Verbindungsobjekte, sodass ich mehrere Funktionen aufrufen kann, ohne jedes Mal eine neue Verbindung zu öffnen. Dieser Mangel an "Transaktionsaffinität" bedeutet, dass, wenn ich eine Datenbank-API-Methode von einer anderen aus aufrufen und beide eine Transaktion verwenden, die verschachtelte Transaktion die Transaktionsisolationsstufe der Transaktion des Aufrufers ändern könnte. Definitiv scheiße. Zum Anfang Ihr Feedback an uns Abhilfe ... für jede C# -Methode, die eine Transaktion verwendet, simulieren Ablaufaffinität für C# -Transaktionen mit C# -Code durch Speichern der Isolationsstufe (dbcc useroptions) und Wiederherstellen vor der Rückkehr! – Triynko

+0

Diese "anwer" sollte ein Kommentar sein. Aber gib mir eine Pause. Es war 2008. :) –

Verwandte Themen