Freigeben über


Verwenden von System.Transactions

Gilt für:SQL Server

Der System.Transactions-Namespace stellt ein Transaktionsframework bereit, das vollständig in ADO.NET- und SQL Server Common Language Runtime (CLR)-Integration integriert ist. Die System.Transactions.TransactionScope-Klasse macht eine Codeblocktransaktion durch implizites Auflisten von Verbindungen in einer verteilten Transaktion.The System.Transactions.TransactionScope class makes a code block transactional by implicitly enlisting connections in a distributed transaction. Sie müssen die Complete-Methode am Ende des Codeblocks aufrufen, der durch die TransactionScopegekennzeichnet ist. Die Dispose-Methode wird aufgerufen, wenn die Programmausführung einen Codeblock verlässt, wodurch die Transaktion nicht mehr wird, wenn die Complete Methode nicht aufgerufen wird. Wenn eine Ausnahme ausgelöst wurde, die bewirkt, dass der Code den Bereich verlässt, wird die Transaktion als nicht mehr unterstützt.

Es wird empfohlen, einen using-Block zu verwenden, um sicherzustellen, dass die Dispose-Methode für das TransactionScope-Objekt aufgerufen wird, wenn der using-Block beendet wird. Fehler beim Commit oder Rollback ausstehender Transaktionen können die Leistung erheblich beeinträchtigen, da das Standardtimeout für die TransactionScope eine Minute beträgt. Wenn Sie keine using-Anweisung verwenden, müssen Sie alle Arbeiten in einem Try-Block ausführen und die Dispose-Methode explizit im Finally-Block aufrufen.

Wenn innerhalb des TransactionScopeeine Ausnahme auftritt, wird die Transaktion als inkonsistent markiert und abgebrochen. Es wird zurückgesetzt, wenn die TransactionScope verworfen wird. Wenn keine Ausnahme auftritt, wird für teilnehmende Transaktionen ein Commit ausgeführt.

TransactionScope sollten nur verwendet werden, wenn auf lokale und Remotedatenquellen oder externe Ressourcenmanager zugegriffen wird, da TransactionScope transaktionen immer höherstufen, auch wenn sie nur innerhalb einer Kontextverbindung verwendet wird.

Die TransactionScope Klasse erstellt standardmäßig eine Transaktion mit einem System.Transactions.Transaction.IsolationLevel von Serializable. Je nach Ihrer Anwendung kann es vorteilhaft sein, die Isolationsstufe herabzusetzen, um ein hohes Konfliktpotenzial in der Anwendung zu vermeiden.

Hinweis

Es empfiehlt sich, nur Updates, Einfügungen und Löschungen innerhalb verteilter Transaktionen für Remoteserver auszuführen, da sie erhebliche Datenbankressourcen in Anspruch nehmen. Wenn der Vorgang auf dem lokalen Server ausgeführt wird, ist keine verteilte Transaktion erforderlich, und eine lokale Transaktion reicht aus. SELECT Anweisungen können Datenbankressourcen unnötig sperren, und in einigen Szenarien ist es möglicherweise erforderlich, Transaktionen für Auswahlen zu verwenden. Jeder Arbeitsschritt, der nicht die Datenbank betrifft, sollte außerhalb des Transaktionsbereichs durchgeführt werden, sofern keine anderen Ressourcen-Manager von der Transaktion betroffen sind.

Eine Ausnahme im Rahmen der Transaktion verhindert zwar, dass die Transaktion committ, die TransactionScope Klasse hat jedoch keine Bereitstellung für das Rollback von Änderungen, die Ihr Code außerhalb des Gültigkeitsbereichs der Transaktion selbst vorsieht. Wenn Sie eine Aktion ausführen müssen, wenn die Transaktion zurückgesetzt wird, müssen Sie ihre eigene Implementierung der System.Transactions.IEnlistmentNotification-Schnittstelle schreiben und die Transaktion explizit auflisten.

Beispiele

Um mit System.Transactionszu arbeiten, benötigen Sie einen Verweis auf die System.Transactions.dll Datei.

Der folgende Code veranschaulicht, wie eine Transaktion erstellt wird, die für zwei verschiedene Instanzen von SQL Server heraufgestuft werden kann. Diese Instanzen werden durch zwei verschiedene System.Data.SqlClient.SqlConnection Objekte dargestellt, die in einen TransactionScope-Block eingeschlossen werden. Der Code erstellt den TransactionScope-Block mit einer using-Anweisung und öffnet die erste Verbindung, die sie automatisch in der TransactionScopeauflistet. Die Transaktion wird anfänglich als einfache Transaktion, nicht als vollständig verteilte Transaktion, eingetragen. Der Code geht davon aus, dass bedingte Logik vorhanden ist (aus Platzgründen weggelassen). Sie öffnet die zweite Verbindung nur, wenn sie benötigt wird, und führt sie in der TransactionScopeein.

Wenn die Verbindung geöffnet wird, wird die Transaktion automatisch auf eine vollständig verteilte Transaktion hochgestuft. Der Code ruft dann TransactionScope.Completeauf, wodurch die Transaktion ausgeführt wird. Der Code entfernt die beiden Verbindungen beim Beenden der using-Anweisungen für die Verbindungen. Die TransactionScope.Dispose Methode für die TransactionScope wird automatisch beim Beenden des using Blocks für die TransactionScopeaufgerufen. Wenn an einem beliebigen Punkt im TransactionScope-Block eine Ausnahme ausgelöst wurde, wird Complete nicht aufgerufen, und die verteilte Transaktion wird zurückgesetzt, wenn die TransactionScope verworfen wird.

using (TransactionScope transScope = new TransactionScope())
{
    using (SqlConnection connection1 = new
       SqlConnection(connectString1))
    {
        // Opening connection1 automatically enlists it in the
        // TransactionScope as a lightweight transaction.
        connection1.Open();

        // Do work in the first connection.

        // Assumes conditional logic in place where the second
        // connection will only be opened as needed.
        using (SqlConnection connection2 = new
            SqlConnection(connectString2))
        {
            // Open the second connection, which enlists the
            // second connection and promotes the transaction to
            // a full distributed transaction.
            connection2.Open();

            // Do work in the second connection.
        }
    }
    //  The Complete method commits the transaction.
    transScope.Complete();
}