Compartilhar via


Transações locais

Aplicável a: .NET Framework .NET .NET Standard

Baixar ADO.NET

As transações do ADO.NET são usadas quando você deseja associar várias tarefas para que elas sejam executadas como uma só unidade de trabalho. Por exemplo, imagine que um aplicativo executa duas tarefas. Primeiro, ele atualiza uma tabela com informações sobre pedidos. Em seguida, ele atualiza uma tabela que contém informações de inventário, debitando os itens pedidos. Se uma das tarefas falhar, as duas atualizações serão revertidas.

Como determinar o tipo de transação

Uma transação é considerada local quando é monofásica e é tratada diretamente pelo banco de dados. Uma transação é considerada distribuída quando é coordenada por um monitor de transação e usa mecanismos à prova de falhas (como o protocolo 2PC) na resolução das transações.

O Provedor de Dados Microsoft SqlClient para SQL Server tem seu objeto SqlTransaction para executar transações locais em bancos de dados do SQL Server. Outros provedores de dados .NET também fornecem os objetos Transaction. Além disso, há uma classe DbTransaction que está disponível para a criação de um código independente de provedor que exige transações.

Observação

As transações são mais eficientes quando são executadas no servidor. Se você estiver trabalhando com um banco de dados do SQL Server que faz uso extensivo de transações explícitas, considere criá-las como procedimentos armazenados usando a instrução Transact-SQL BEGIN TRANSACTION.

Como executar uma transação usando uma só conexão

No ADO.NET, você controla as transações com o objeto Connection. É possível iniciar uma transação local com o método BeginTransaction. Depois de iniciar uma transação, você pode inscrever um comando nessa transação com a propriedade Transaction de um objeto Command. Em seguida, você poderá confirmar ou reverter todas as modificações feitas na fonte de dados com base no êxito ou na falha dos componentes de transação.

Observação

O método EnlistDistributedTransaction não deve ser usado para uma transação local.

O escopo da transação é limitado à conexão. O exemplo a seguir executa uma transação explícita que consiste em dois comandos separados no bloco try. Os comandos executam as instruções INSERT na tabela Production.ScrapReason do banco de dados de exemplo AdventureWorks do SQL Server, as quais são confirmadas se nenhuma exceção é gerada. O código no bloco catch reverterá a transação se uma exceção for lançada. Se a transação for anulada ou a conexão for fechada antes de a transação ser concluída, a transação será automaticamente revertida.

Exemplo

Siga estas etapas para executar uma transação.

  1. Chame o método BeginTransaction do objeto SqlConnection para marcar o início da transação. O método BeginTransaction retorna uma referência à transação. Essa referência é atribuída aos objetos SqlCommand inscritos na transação.

  2. Atribua o objeto Transaction à propriedade Transaction de SqlCommand a ser executado. Se um comando for executado em uma conexão com uma transação ativa, e o objeto Transaction não tiver sido atribuído à propriedade Transaction do objeto Command, uma exceção será gerada.

  3. Execute os comandos necessários.

  4. Chame o método Commit do objeto SqlTransaction para concluir a transação, ou chame o método Rollback para finalizar a transação. Se a conexão for fechada ou descartada antes do método Commit ou Rollback ser executado, a transação será revertida.

O exemplo de código a seguir demonstra a lógica transacional usando o Provedor de Dados Microsoft SqlClient para SQL Server.

using System;
using Microsoft.Data.SqlClient;

class Program
{
    static void Main(string[] args)
    {
        string connectionString = "Data Source = localhost; Integrated Security = true; Initial Catalog = AdventureWorks";

        using (SqlConnection connection = new SqlConnection(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);
                }
            }
        }
    }
}

Confira também