Maneira mais limpa de usar BeginTransaction usando try catch
Até agora estou usando dois blocos try catch para minhas consultas. O primeiro irá gerar um erro se a conexão não for estabelecida. O segundo verifica se SqlCommand
foi executado com sucesso. Como o exemplo abaixo
try
{
using(varconnection=newSqlConnection())
using(varcmd=newSqlCommand())
{
connection.Open();
var transaction=connection.BeginTransaction();
cmd.Connection=connection;
cmd.Transaction=transaction;
try
{
cmd.CommandText="InsertintoCustomers(Name)values('Dimitri')";
cmd.ExecuteNonQuery();
cmd.CommandText="InsertintoCustomers(Name)values('George')";
cmd.ExecuteNonQuery();
transaction.Commit();
}
catch
{
try{transaction.Rollback();}catch{}
}
}
}
catch
{
}
Encontrei um segundo exemplo que parece mais claro para mim.
SqlTransactiontransaction=null;
using(varconnection=newSqlConnection())
using(varcmd=newSqlCommand())
{
try
{
connection.Open();
transaction=connection.BeginTransaction();
cmd.Connection=connection;
cmd.Transaction=transaction;
cmd.CommandText="InsertintoCustomers(Name)values('Dimitri')";
cmd.ExecuteNonQuery();
cmd.CommandText="InsertintoCustomers(Name)values('George')";
cmd.ExecuteNonQuery();
transaction.Commit();
transaction.Dispose();
transaction=null;
}
catch
{
if(transaction!=null)
{
try{transaction.Rollback();}catch{}
}
}
}
Ambos estão tendo o mesmo resultado? Qual dos dois é mais preferível?
Respostas
Nenhum desses dois métodos é bom. Eles são muito prolixos.
O melhor método é apenas colocar o Transaction
em using
também, também devemos usar um parâmetro para a consulta:
using(var connection = new SqlConnection(connString))
using(var cmd = new SqlCommand("Insert into Customers (Name) values (@Name));"))
{
var param = cmd.Parameters.Add("@Name", SqlDbType.VarChar, insert_column_length_here);
connection.Open();
using(var transaction = connection.BeginTransaction())
{
cmd.Transaction = transaction;
param.Value = "Dimitri";
cmd.ExecuteNonQuery();
param.Value = "George";
cmd.ExecuteNonQuery();
transaction.Commit();
}
}
Podemos ver que descartar o objeto de transação será revertido automaticamente, se ainda não tiver sido confirmado, observando o código-fonte . Então, using
vai limpar tudo.
Se precisar exibir uma mensagem para o usuário, faça-o fora do código, ou seja, coloque um em try/catch
volta de tudo. Não faça você mesmo o código de limpeza