Подтвердить что ты не робот

Зачем использовать оператор using с SqlTransaction?

У меня возникли проблемы с SqlTransaction, которые я использую в своем коде. Во время моего Googling я вижу много людей, использующих инструкцию using с SqlTransaction.

Какова польза и/или разница в использовании этого типа оператора с помощью SqlTransaction?

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

В настоящее время мой код выглядит следующим образом:

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

В чем преимущество одного способа над другим?

4b9b3361

Ответ 1

Оператор

A using должен использоваться каждый раз, когда вы создаете экземпляр класса, который реализует IDisposable в пределах области блока. Это гарантирует, что метод Dispose() будет вызываться в этом экземпляре, независимо от того, выбрано ли исключение.

В частности, ваш код только улавливает управляемые исключения, а затем разрушает фрейм стека, вызывая новое исключение вместо повторного создания существующего.

Правильный способ сделать это:

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

Обратите внимание, что если ваш класс имеет экземпляры экземпляров типов, реализующих IDisposable, то ваш класс должен реализовать IDisposable сам и удалять эти члены во время своего собственного вызова Dispose().

Ответ 2

Причиной этого является то, что объект SqlTransaction откатится в своем методе Dispose(), если он явно не был зафиксирован (например, если выбрано исключение). Другими словами, он имеет тот же эффект, что и ваш код, немного чище.

Ответ 3

По сути, использование делает то же самое, что вы делаете, за исключением int finally block вместо того, чтобы ловить все исключения:

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

- это то же самое, что и намного меньше кода:)

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

Ответ 4

В конце концов, using является просто ярлыком для шаблона. Но это очень полезный и полезный ярлык, потому что он гарантирует правильность реализации шаблона и означает, что вы можете сделать это с меньшим количеством кода.

В этом случае вы неправильно реализовали шаблон. Что происходит в вашем коде, если вызов tr.RollBack() также вызывает исключение?

Ответ 5

using statement закрывает и удаляет ваше соединение и транзакцию для вас. Это эквивалент наличия блока finally на вашем try/catch, который делает dispose.

Вы могли бы также сконденсировать блоки использования, как это...

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

который будет примерно таким же, как:

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

Ответ 6

Если вы не используете блок using(), вам придется явно вызвать метод .Dispose() объектов SqlConnection и SqlTransaction. Если вы этого не сделаете, тогда неуправляемые ресурсы не будут выпущены и могут вызвать утечку памяти или другие проблемы.

Ответ 7

В дополнение ко всему этому он преувеличивает ваш код. Разве 7 строк кода выглядят лучше, чем 14 строк? Я чувствую облегчение каждый раз, когда вижу блок. Это похоже на ту маленькую шкуру тумана, которая исходит из этой радостной вонючей вещи. Ммм, я довольно эффективный код. Посмотрите, насколько хорошо я управляю памятью и насколько приятен я для глаз.

Ответ 8

Использование gurantees в том, что ваш объект соединения будет удален после возврата кода. Dispose полезен для освобождения ресурсов unmanages. Как хорошая практика, если объект реализует IDisposable, метод dispose всегда следует называть