Caro(a) Leitor(a), hoje em dia para desenvolver um sistema é necessário entender de vários atributos e tecnologias, por exemplo: se for web, você precisa saber javascript, html, componentes da ferramenta / linguagem que está desenvolvendo e dependendo do banco de dados você precisa usar o driver de conexão.

Existem vários drivers de conexão hoje em dia, incluindo os nativos e os que precisam instalar no seu sistema operacional. Muita gente hoje utiliza a conexão com o banco de dados para gravar informações e as vezes em uma mesma transação.

Em alguns casos o sistema precisa inserir o usuário, buscar o id dele inserido e inserir em outra tabela. Pra fazer isso usando linguagem de programação pode ser um pouco problemático ou se tiver vários usuários acessando a mesma aplicação esse vínculo pode não funcionar como gostaria.

Para isso nós temos o início de uma transação, commit ou rollback quando falamos de banco de dados. Para alegria do desenvolvedor, a Microsoft adicionou uma classe junto do Framework .NET chamada Transaction, que deriva de System.

Essa classe ajuda a manter a transação aberta para fazer todas as gravações necessárias no banco de dados, se houver algum erro, toda a transação será desfeita rapidamente. Se for tudo ok, a transação será fechada com o método Complete() automaticamente.

Essa System.Transaction funciona para o .NET Framework versão 2.0, 3.0, 3.5, 4.0 e 4.5. Para o .NET Framework Client Profile um pouco mais leve e simples funciona para as versões 3.5 SP1 e 4.0.

As plataformas que funcionam são: Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 e Windows Server 2008 R2. Lembro que o .NET Framework não funciona em todas as versões de todas as plataformas.

Passando agora para o exemplo e como utilizar essa classe, basta primeiro impostar a dll de referência no Visual Studio chamada System.Transactions. Coloque no topo da sua classe o using System.Transactions.

Depois basta utilizar na sua classe responsável por fazer várias transações ao mesmo tempo e quando tudo der certo a operação é realmente concretizada. Se algum erro no caminho acontecer, tudo será desfeito.



O responsável por manter esta transação é o TransactionScope. Depois de usar a classe, basta colocar o using e dentro dele os comandos, code 1.1.

int returnValue = 0;
using (TransactionScope scope = new TransactionScope())
{}


Code 1.1 - Criando um escopo para transação

Todo o código precisa ficar dentro desse using para manter a transação. Vamos continuar com o exemplo. Agora vou fazer a conexão com o banco de dados, abrir o banco e exercutar o comando, code 1.2.

using (SqlConnection connection1 = new SqlConnection(connectString1))
{
connection1.Open();

SqlCommand command1 = new SqlCommand(commandText1, connection1);
     returnValue = command1.ExecuteNonQuery();
}
Code 1.2 - Conexão com o banco de dados

O código 1.2 mostra que a conexão está sendo instanciada e o comando texto sendo executado, para ser o ExecuteNonQuery() o comando tem que ser INSERT, UPDATE ou DELETE.

Depois desse código, preciso fazer outra conexão para executar outro comando. Vamos dizer que a primeira execução foi um INSERT e a segunda execução um UPDATE com os dados do primeiro INSERT. Vamos para a segunda conexão então, code 1.3.

using (SqlConnection connection2 = new SqlConnection(connectString2))
{
connection2.Open();

     
returnValue = 0;
SqlCommand command2 = new SqlCommand(commandText2, connection2);
returnValue = command2.ExecuteNonQuery();
writer.WriteLine("Rows to be affected by command2: {0}", returnValue);
}
Code 1.3 - Fazendo uma segunda conexão, dentro da primeira.



No final do código e ainda dentro do using do scope é necessário chamar o método scode.Complete(). Ele complete a transação fazendo o Commit() nas duas transações e se alguma transação der errado, automaticamente será chamado o método Rollback; você não precisa se preocupar com isso.

Vou colocar aqui todo o código para entender melhor, code 1.4.

// Iniciando a variável de retorno
    int returnValue = 0;

    try
    {
        // Criando o escopo de transacao 
        // Conexando no banco de dados 
        using (TransactionScope scope = new TransactionScope())
        {
            using (SqlConnection connection1 = new SqlConnection(connectString1))
            {
                // Abrindo a conexao 
                // Dentro do escopo
                connection1.Open();

                // Criando o sqlcommand para executar
                SqlCommand command1 = new SqlCommand(commandText1, connection1);
                returnValue = command1.ExecuteNonQuery();
                writer.WriteLine("O comando foi executado: {0}", returnValue);

                // Se o código chegou até aqui, quer dizer que o comando foi bem sucessido até agora.

                // Usando outro bloco de conexao, a conexao2.
                using (SqlConnection connection2 = new SqlConnection(connectString2))
                {
                    connection2.Open();

                    returnValue = 0;
                    SqlCommand command2 = new SqlCommand(commandText2, connection2);
                    returnValue = command2.ExecuteNonQuery();
                    writer.WriteLine("Comando 2 executado com sucesso: {0}", returnValue);
                }
            }

            // Para completar a transação, o método Complete é chamado.
            // Se esse método não foi chamado, automaticamente o Rollback é chamado e tudo feito anteriormente é desfeito.
            scope.Complete();

        }

    }
    catch (TransactionAbortedException ex)
    {
        writer.WriteLine("TransactionAbortedException Mensagem: {0}", ex.Message);
    }
    catch (ApplicationException ex)
    {
        writer.WriteLine("ApplicationException Mensagem: {0}", ex.Message);
    }

    // Mostra as mensagens
    Console.WriteLine(writer.ToString());
Code 1.4 - Todo o método de exemplo

Bom, esta foi a classe que fala de transação do sistema usando banco de dados de uma maneira simples e fácil. Lembro que, pelos meus testes, esta classe não funciona para o banco de dados local .sdf SQLCe. 

Qualquer dúvida, pode entrar em contato pelo site ou pelo meu site www.mauriciojunior.org. Até a próxima.