Il modo più pulito per utilizzare BeginTransaction utilizzando try catch
Fino ad ora sto usando due blocchi try catch per le mie query. Il primo genererà un errore se la connessione non viene stabilita. Il secondo controlla se SqlCommand
viene eseguito con successo. Come nell'esempio di seguito
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
{
}
Ho trovato un secondo esempio che mi sembra più chiaro.
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{}
}
}
}
Entrambi hanno lo stesso risultato? Quale dei due è più preferibile?
Risposte
Nessuno di questi due metodi è buono. Sono troppo prolissi.
Il metodo migliore è inserire anche il Transaction
in a using
, inoltre dovremmo usare un parametro per la query:
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();
}
}
Possiamo vedere che la disposizione dell'oggetto transazione verrà automaticamente ripristinata se non è già stata confermata, osservando il codice sorgente . Quindi using
pulirà tutto.
Se hai bisogno di intercettare per mostrare un messaggio all'utente, fallo fuori dal codice, cioè metti un try/catch
intorno all'intera cosa. Non eseguire da solo il codice di pulizia