Manière la plus propre d'utiliser BeginTransaction en utilisant try catch

Jan 28 2021

Jusqu'à présent, j'utilise deux blocs try catch pour mes requêtes. Le premier lancera une erreur si la connexion n'est pas établie. Le second vérifie si SqlCommandest exécuté avec succès. Comme l'exemple ci-dessous

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
{

}

J'ai trouvé un deuxième exemple qui me semble plus clair.

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{}
   }
 }
}

Les deux ont-ils le même résultat? Lequel des deux est le plus préférable?

Réponses

2 Charlieface Jan 28 2021 at 00:18

Aucune de ces deux méthodes n'est bonne. Ils sont trop verbeux.

La meilleure méthode est de simplement mettre le Transactiondans un usingaussi, nous devrions également utiliser un paramètre pour la requête:

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();
    }
}

Nous pouvons voir que la suppression de l'objet de transaction sera automatiquement annulée s'il n'est pas déjà validé, en regardant le code source . Donc usingva tout nettoyer.

Si vous avez besoin de rattraper pour afficher un message à l'utilisateur, faites-le en dehors du code, c'est-à-dire mettez un try/catchautour du tout. Ne faites pas le code de nettoyage vous-même