web-dev-qa-db-fra.com

Pourquoi utiliser une instruction using avec une SqlTransaction?

J'ai rencontré des problèmes concernant une SqlTransaction que j'utilise dans mon code. Au cours de ma recherche sur Google, je vois de nombreuses personnes utiliser une instruction using avec une SqlTransaction.

Quel est l'avantage et/ou la différence de l'utilisation de ce type de déclaration avec une SqlTransaction?

using (SqlConnection cn = new SqlConnection())
{
     using (SqlTransaction tr = cn.BeginTransaction())
     {
      //some code
      tr.Commit();
     }
}

Actuellement, mon code ressemble à ceci:

SqlConnection cn = new SqlConnection(ConfigurationManager.AppSettings["T3"]);
cn.Open();
SqlTransaction tr = cn.BeginTransaction();

try
{
     //some code
     tr.Commit();
     cn.Close();
}
catch(Exception ex)
{
      tr.Rollback();
      cn.Close();
      throw ex;
}

Quel est l'avantage d'une manière par rapport à l'autre?

47
MDStephens

Une instruction using doit être utilisée chaque fois que vous créez une instance d'une classe qui implémente IDisposabledans le cadre d'un bloc. Il garantit que la méthode Dispose() sera appelée sur cette instance, qu'une exception soit levée ou non.

En particulier, votre code intercepte uniquement les exceptions gérées, puis détruit le cadre de pile en lançant une nouvelle exception au lieu de renvoyer l'existant.

La bonne façon de procéder est:

using (SqlConnection cn = new SqlConnection(ConfigurationManager.AppSettings["T3"])) {
    cn.Open();
    using (SqlTransaction tr = cn.BeginTransaction()) {
        //some code
        tr.Commit();
    }
}

Notez que si votre classe a des membres d'instance de types qui implémentent IDisposable, alors votre classe doit implémenter IDisposable elle-même et supprimer ces membres lors de son propre appel Dispose().

57
John Saunders

La raison en est que l'objet SqlTransaction sera restauré dans sa méthode Dispose () s'il n'a pas été explicitement validé (par exemple si une exception est levée). En d'autres termes, il a le même effet que votre code, juste un peu plus propre.

26
Ken Keenan

Essentiellement, l'utilisation fait la même chose que vous, sauf dans un bloc finally au lieu d'attraper toutes les exceptions:

using (SqlConnection cn = new SqlConnection())
{
     using (SqlTransaction tr = cn.BeginTransaction())
     {
      //some code
      tr.Commit();
     }
}

est le même que, beaucoup moins de code :)

{
    SqlConnection cn = null;
    try
    {
       cn = new SqlConnection();
       {
           SqlTransaction tr = null;
           try
           {
               tr = cn.BeginTransaction())

               //some code
               tr.Commit();
            }
            finally
            {
                if(tr != null && tr is IDisposable)
                {
                    tr.Dispose();
                }
            }
        }
    }
    finally
    {
        if(cn != null && cn is IDisposable)
        {
            cn.Dispose();
        }
    }
}
15
heavyd

Au final, using n'est qu'un raccourci pour un motif. Mais c'est un raccourci très tile et utile, car il garantit que vous implémentez le modèle correctement et signifie que vous pouvez le faire avec moins de code.

Dans ce cas, vous n'avez pas correctement implémenté le modèle. Que se passe-t-il dans votre code si l'appel à tr.RollBack() lève également une exception?

6
Joel Coehoorn

en utilisant l'instruction ferme et supprime votre connexion et transaction pour vous. C'est l'équivalent d'avoir un bloc enfin sur votre try/catch qui fait la disposition.

Vous pouvez également condenser les blocs à l'aide d'un peu comme ceci ...

using (SqlConnection cn = new SqlConnection())
using (SqlTransaction tr = cn.BeginTransaction())     
{
      //some code
      tr.Commit();
}

qui serait à peu près le même que:

SqlConnection cn = null;
SqlTransaction tr = null;
try
{
    cn = new SqlConnection());
    tr = cn.BeginTransaction());

    //some code
    tr.Commit();
}
finally
{
    if (cn != null)
        cn.Dispose();
    if (tr != null)    
        tr.Dispose();
}
4
Scott Ivey

Si vous n'utilisez pas de bloc using (), vous devrez appeler explicitement la méthode .Dispose () des objets SqlConnection et SqlTransaction. Si vous ne le faites pas, les ressources non gérées ne seront pas libérées et pourraient provoquer des fuites de mémoire ou d'autres problèmes.

3
Matthew Groves

En plus de tout cela, il embellit votre code. Les 7 lignes de code ne sont-elles pas plus belles que les 14 lignes? Je respire un signe de soulagement chaque fois que je vois un bloc d'utilisation. C'est comme ce petit jet de brume qui sort de cette joyeuse odeur. Mmm, je suis un joli bloc de code efficace. Regardez à quel point je gère bien la mémoire et à quel point je suis agréable à l'œil.

2
Levitikon

En utilisant des garanties, votre objet de connexion sera supprimé après le retour du code. Dispose est utile pour libérer les ressources non gérées. En tant que bonne pratique, si un objet implémente IDisposable, la méthode dispose doit toujours être appelée

1
jyotishka bora

L'instruction Using est un raccourci pour gérer correctement une ressource. Vous pouvez trouver plus d'informations sur article MSDN sur l'utilisation de l'instruction

0
pdwetz