Partilhar via


Transações Locais

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

Determinando o tipo de transação

Uma transação é considerada uma transação local quando é uma transação monofásica e é tratada diretamente pelo banco de dados. Uma transação é considerada uma transação distribuída quando é coordenada por um monitor de transações e usa mecanismos à prova de falhas (como confirmação em duas fases) para a resolução da transação.

Cada um dos provedores de dados do .NET Framework tem seu próprio Transaction objeto para executar transações locais. Se você precisar que uma transação seja executada em um banco de dados do SQL Server, selecione uma System.Data.SqlClient transação. Para uma transação Oracle, use o System.Data.OracleClient provedor. Além disso, há uma DbTransaction classe que está disponível para escrever código independente do provedor que requer transações.

Nota

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

Executando uma transação usando uma única conexão

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

Nota

O EnlistDistributedTransaction método 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 try bloco . Os comandos executam instruções INSERT na tabela Production.ScrapReason no banco de dados de exemplo do SQL Server AdventureWorks, que são confirmadas se nenhuma exceção for lançada. O código no bloco reverte catch a transação se uma exceção for lançada. Se a transação for abortada ou a conexão for fechada antes da conclusão da transação, ela será revertida automaticamente.

Exemplo

Siga estas etapas para executar uma transação.

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

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

  3. Execute os comandos necessários.

  4. Chame o CommitSqlTransaction método do objeto para concluir a transação ou chame o Rollback método para finalizar a transação. Se a conexão for fechada ou descartada antes que os Commit métodos ou Rollback tenham sido executados, a transação será revertida.

O exemplo de código a seguir demonstra a lógica transacional usando ADO.NET com o Microsoft SQL Server.

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

Consulte também