Lokale Transaktionen

Transaktionen werden in ADO.NET verwendet, wenn mehrere Aufgaben miteinander verbunden werden sollen, damit sie als eine einzige Verarbeitungseinheit ausgeführt werden können. Stellen Sie sich z. B. vor, dass eine Anwendung zwei Aufgaben ausführt. Zum einen aktualisiert sie eine Tabelle mit Bestellinformationen. Zum anderen aktualisiert sie eine Tabelle mit Bestandsinformationen und bucht die bestellten Artikel ab. Wenn bei einem der Tasks ein Fehler auftritt, wird für beide Updates ein Rollback ausgeführt.

Bestimmen des Transaktionstyps

Eine Transaktion wird als lokale Transaktion angesehen, wenn sie über nur eine Phase verfügt und direkt von der Datenbank verarbeitet wird. Als verteilte Transaktion wird eine Transaktion angesehen, wenn sie von einem Transaktionsmonitor koordiniert wird und für die Transaktionsauflösung ausfallsichere Mechanismen verwendet werden (z. B. Zweiphasencommit).

Die einzelnen .NET Framework-Datenanbieter verfügen jeweils über ein eigenes Transaction-Objekt für das Ausführen lokaler Transaktionen. Wählen Sie eine System.Data.SqlClient-Transaktion, wenn eine Transaktion in einer SQL Server-Datenbank ausgeführt werden muss. Verwenden Sie für eine Oracle-Transaktion den System.Data.OracleClient-Anbieter. Darüber hinaus gibt es eine DbTransaction-Klasse zum Schreiben von anbieterunabhängigem Code, der Transaktionen erfordert.

Hinweis

Transaktionen sind am effizientesten, wenn sie auf dem Server durchgeführt werden. Wenn Sie mit einer SQL Server-Datenbank arbeiten, die häufig explizite Transaktionen verwendet, empfiehlt es sich, die Transaktionen unter Verwendung der BEGIN TRANSACTION-Anweisung von Transact-SQL als gespeicherte Prozeduren zu schreiben.

Ausführen einer Transaktion unter Verwendung einer einzelnen Verbindung

In ADO.NET können Sie Transaktionen mit dem Connection-Objekt steuern. Zum Initiieren einer lokalen Transaktion steht Ihnen die BeginTransaction-Methode zur Verfügung. Nachdem Sie eine Transaktion gestartet haben, können Sie mit der Transaction-Eigenschaft eines Command-Objekts einen Befehl in dieser Transaktion eintragen. Dann können Sie für Änderungen an der Datenquelle auf Grundlage des Erfolgs oder Fehlschlags der Komponenten der Transaktion einen Commit oder Rollback ausführen.

Hinweis

Die EnlistDistributedTransaction-Methode darf nicht für eine lokale Transaktion verwendet werden.

Der Gültigkeitsbereich der Transaktion ist auf die Verbindung beschränkt. Im folgenden Beispiel wird eine explizite Transaktion ausgeführt, die aus zwei separaten Befehlen im try-Block besteht. Die Befehle führen INSERT-Anweisungen für die Production.ScrapReason-Tabelle in der AdventureWorks-Beispieldatenbank von SQL Server aus. Wenn keine Ausnahmen ausgelöst werden, werden die Anweisungen übergeben. Der Code im catch-Block führt ein Rollback der Transaktion aus, wenn eine Ausnahme ausgelöst wird. Wenn die Transaktion abgebrochen oder die Verbindung geschlossen wird, bevor die Transaktion beendet wurde, wird automatisch ein Rollback für die Transaktion ausgeführt.

Beispiel

Führen Sie diese Schritte aus, um eine Transaktion auszuführen:

  1. Rufen Sie die BeginTransaction-Methode des SqlConnection-Objekts auf, um den Start der Transaktion festzulegen. Die BeginTransaction-Methode gibt einen Verweis auf die Transaktion zurück. Dieser Verweis wird den SqlCommand-Objekten zugeordnet, die in der Transaktion eingetragen sind.

  2. Weisen Sie das Transaction-Objekt der Transaction-Eigenschaft des auszuführenden SqlCommand zu. Wenn ein Befehl für eine Verbindung mit einer aktiven Transaktion ausgeführt wird und das Transaction-Objekt nicht der Transaction-Eigenschaft des Command-Objekts zugewiesen wurde, wird eine Ausnahme ausgelöst.

  3. Führen Sie die erforderlichen Befehle aus.

  4. Rufen Sie die Commit-Methode des SqlTransaction-Objekts auf, um die Transaktion abzuschließen, oder rufen Sie die Rollback-Methode auf, um die Transaktion zu beenden. Wenn die Verbindung vor dem Ausführen der Commit-Methode oder der Rollback-Methode geschlossen oder verworfen wurde, wird für die Transaktion ein Rollback ausgeführt.

Im folgenden Codebeispiel wird die Transaktionslogik unter Verwendung von ADO.NET mit Microsoft SQL Server veranschaulicht.

using (SqlConnection connection = new(connectionString))
{
    connection.Open();

    // Start a local transaction.
    SqlTransaction sqlTran = connection.BeginTransaction();

    // Enlist a command in the current transaction.
    SqlCommand command = connection.CreateCommand();
    command.Transaction = sqlTran;

    try
    {
        // Execute two separate commands.
        command.CommandText =
          "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')";
        command.ExecuteNonQuery();
        command.CommandText =
          "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')";
        command.ExecuteNonQuery();

        // Commit the transaction.
        sqlTran.Commit();
        Console.WriteLine("Both records were written to database.");
    }
    catch (Exception ex)
    {
        // Handle the exception if the transaction fails to commit.
        Console.WriteLine(ex.Message);

        try
        {
            // Attempt to roll back the transaction.
            sqlTran.Rollback();
        }
        catch (Exception exRollback)
        {
            // Throws an InvalidOperationException if the connection
            // is closed or the transaction has already been rolled
            // back on the server.
            Console.WriteLine(exRollback.Message);
        }
    }
}
Using connection As New SqlConnection(connectionString)
    connection.Open()

    ' Start a local transaction.
    Dim sqlTran As SqlTransaction = connection.BeginTransaction()

    ' Enlist a command in the current transaction.
    Dim command As SqlCommand = connection.CreateCommand()
    command.Transaction = sqlTran

    Try
        ' Execute two separate commands.
        command.CommandText = _
          "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')"
        command.ExecuteNonQuery()
        command.CommandText = _
          "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')"
        command.ExecuteNonQuery()

        ' Commit the transaction
        sqlTran.Commit()
        Console.WriteLine("Both records were written to database.")

    Catch ex As Exception
        ' Handle the exception if the transaction fails to commit.
        Console.WriteLine(ex.Message)

        Try
            ' Attempt to roll back the transaction.
            sqlTran.Rollback()

        Catch exRollback As Exception
            ' Throws an InvalidOperationException if the connection 
            ' is closed or the transaction has already been rolled 
            ' back on the server.
            Console.WriteLine(exRollback.Message)
        End Try
    End Try
End Using

Siehe auch