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.