Sdílet prostřednictvím


Místní transakce

Transakce v ADO.NET se používají, když chcete svázat více úkolů dohromady, aby se spouštěly jako jedna jednotka práce. Představte si například, že aplikace provede dvě úlohy. Nejprve aktualizuje tabulku s informacemi o objednávce. Za druhé aktualizuje tabulku, která obsahuje informace o inventáři a inkasuje objednané položky. Pokud některý z úkolů selže, vrátí se obě aktualizace zpět.

Určení typu transakce

Transakce se považuje za místní transakci, pokud se jedná o jednofázovou transakci a zpracovává ji přímo databáze. Transakce se považuje za distribuovanou transakci, když je koordinovaná monitorováním transakcí a používá mechanismy bezpečné pro selhání (například dvoufázové potvrzení) pro řešení transakcí.

Každý z poskytovatelů dat rozhraní .NET Framework má svůj vlastní Transaction objekt pro provádění místních transakcí. Pokud potřebujete provést transakci v databázi SQL Serveru, vyberte System.Data.SqlClient transakci. Pro transakci Oracle použijte System.Data.OracleClient poskytovatele. Kromě toho je DbTransaction k dispozici třída, která je k dispozici pro psaní kódu nezávislého na poskytovateli, který vyžaduje transakce.

Poznámka:

Transakce jsou nejúčinnější při provádění na serveru. Pokud pracujete s databází SQL Serveru, která provádí rozsáhlé využití explicitních transakcí, zvažte jejich zápis jako uložené procedury pomocí příkazu Transact-SQL BEGIN TRANSACTION.

Provedení transakce pomocí jediného Připojení ionu

V ADO.NET řídíte transakce s objektem Connection . S metodou BeginTransaction můžete zahájit místní transakci. Jakmile začnete transakci, můžete do této transakce zahrnout příkaz s Transaction vlastností objektu Command . Změny provedené ve zdroji dat pak můžete potvrdit nebo vrátit zpět na základě úspěchu nebo selhání komponent transakce.

Poznámka:

Metoda EnlistDistributedTransaction by neměla být použita pro místní transakci.

Rozsah transakce je omezen na připojení. Následující příklad provádí explicitní transakci, která se skládá ze dvou samostatných příkazů v try bloku. Příkazy spouštějí příkazy INSERT proti tabulce Production.ScrapReason v ukázkové databázi AdventureWorks SQL Serveru, které jsou potvrzeny, pokud nejsou vyvolány žádné výjimky. Kód v catch bloku vrátí transakce zpět, pokud je vyvolán výjimka. Pokud je transakce přerušena nebo je připojení uzavřeno před dokončením transakce, automaticky se vrátí zpět.

Příklad

K provedení transakce použijte tento postup.

  1. BeginTransaction Volání metody objektu SqlConnection označit začátek transakce. Metoda BeginTransaction vrátí odkaz na transakci. Tento odkaz je přiřazen k SqlCommand objektům, které jsou zařazeny do transakce.

  2. Transaction Přiřaďte objekt vlastnostiTransaction, která SqlCommand se má provést. Pokud je příkaz proveden na připojení s aktivní transakcí a Transaction objekt nebyl přiřazen k Transaction vlastnosti objektu Command , je vyvolána výjimka.

  3. Spusťte požadované příkazy.

  4. Commit Volání metody objektu SqlTransaction k dokončení transakce, nebo volání Rollback metody pro ukončení transakce. Pokud je připojení uzavřeno nebo uvolněno před provedením Commit nebo Rollback metody, transakce se vrátí zpět.

Následující příklad kódu ukazuje transakční logiku pomocí ADO.NET s Microsoft SQL Serverem.

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

Viz také