Najczystszy sposób korzystania z BeginTransaction przy użyciu try catch
Do tej pory używam dwóch bloków try catch dla moich zapytań. Pierwsza z nich zgłosi błąd, jeśli połączenie nie zostanie nawiązane. Drugi sprawdza, czy SqlCommand
został wykonany pomyślnie. Jak w przykładzie poniżej
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
{
}
Znalazłem drugi przykład, który wydaje mi się bardziej przejrzysty.
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{}
}
}
}
Czy obaj mają ten sam wynik? Który z dwóch jest lepszy?
Odpowiedzi
Żadna z tych dwóch metod nie jest dobra. Są zbyt szczegółowe.
Najlepszą metodą jest po prostu wstawienie Transaction
również using
a, również powinniśmy użyć parametru w zapytaniu:
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();
}
}
Widzimy, że pozbycie się obiektu transakcji spowoduje automatyczne wycofanie, jeśli nie zostało jeszcze zatwierdzone , patrząc na kod źródłowy . Więc using
wszystko posprząta.
Jeśli chcesz złapać, aby wyświetlić wiadomość dla użytkownika, zrób to poza kodem, tj. Umieść wszystko try/catch
wokół. Nie rób samodzielnie kodu porządkującego