Il modo più pulito per utilizzare BeginTransaction utilizzando try catch

Jan 27 2021

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 SqlCommandviene 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

2 Charlieface Jan 28 2021 at 00:18

Nessuno di questi due metodi è buono. Sono troppo prolissi.

Il metodo migliore è inserire anche il Transactionin 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 usingpulirà tutto.

Se hai bisogno di intercettare per mostrare un messaggio all'utente, fallo fuori dal codice, cioè metti un try/catchintorno all'intera cosa. Non eseguire da solo il codice di pulizia