2017-02-06 20 views
0

Каков правильный способ обработки исключения внутри вложенного оператора using? У меня есть следующая часть кода:Ловкое исключение внутри вложенного Использование инструкции NHibernate

public void Create(Entity entity) 
{ 
    try 
    { 
     using (ISession session = NhibernateHelper.OpenSession()) 
     { 
      try 
      { 
       using (ITransaction transaction = session.BeginTransaction()) 
       { 
        session.Save(entity); 
        transaction.Commit(); 
       } 
      } 
      catch (TransactionException transactionException) 
      { 
       // log it 
       throw; 
      } 
     } 
    } 
    catch (TransactionException transactionException) 
    { 
     // log it 
     throw; 
    } 
    catch (SessionException sessionException) 
    { 
     // log it 
     throw; 
    } 
    catch (Exception exception) 
    { 
     // log it 
     throw; 
    } 
} 

Я видел несколько ответов, когда люди устанавливали инструкцию try/catch внутри вложенного использования. Я знаю, что использование инструкции состоит из try/finally. И мой вопрос заключается в правильном пути, чтобы поймать все возможные исключения. Должен ли я выполнять откаты внутри одного из операторов catch? Не могли бы вы предоставить мне правильный способ сделать это?

+0

Вы используете это в веб-приложении? MVC? WinForms? потому что на первый взгляд, я бы сказал, что вы не хотите, чтобы в вашем приложении выглядел такой код. – Fran

ответ

2

Я стараюсь как можно больше свести к минимуму положения «попробуйте уловить».

Вложение «try catch» и регистрация каждого улова (хотя и не исключение глотания) могут приводить к тому, что одно и то же исключение регистрируется несколько раз, что раздувает журналы. И «попробуй поймать» повсюду раздувает код.

Я не вижу необходимости явного отката неудачной транзакции: нефиксированная транзакция отменяется по умолчанию.

Мой обычный шаблон с MVC/webform должен использовать глобальный фильтр действий (обычно полученный от HandleErrorAttribute) для исключения журнала и/или выделенный IHttpModule. Поэтому нет необходимости «проверять уловы» в другом месте только для ведения журнала, не проглатывая исключение.

(С MVC, я обычно явно откатить неудачной сделки, потому что я использую фильтр действий для открытия их OnActionExecuting, совершающих или отката на предыдущую версию их OnActionExecuted в зависимости от filterContext состояния. Там, особенно если произошла ошибка, я могу добавить глотание и зарегистрированный try catch вокруг отката: он также может не работать, и я считаю, что этот сбой не должен замаскировать тот, который заставил приложение попробовать откатить.)

+0

А как насчет 'ExceptionFilterAttribute' и' OnException' метода? Должен ли я использовать инструкции try/catch, если я его использую? –

+1

Не обязательно. Personnaly, я часто делаю глотание (но с журналами), пытаюсь поймать код обработки ошибок, чтобы избежать маскировки исходной ошибки с помощью другой ошибки/ошибки в коде обработки ошибок: мой приоритет - получить информацию о бизнес-исключении, а не об ошибке обработки ошибок. –

0

Я следую схеме, всегда начинаю попытку. Блок сразу после BeginTransaction().

Кроме этого, я думаю, что не нужно добавлять какие-либо другие проверки исключений - просто позвольте ему распространиться на вызывающий код.

using (var session = NhibernateHelper.OpenSession()) 
{ 
     using(var transaction = session.BeginTransaction()) 
     { 
      try 
      { 
       // 
       // Add a block of code here which queries and 
       // modifies data 
       // 
       // 
       transaction.Commit(); 
      } 
      catch(Exception ex) 
      { 
       transaction.RollBack(); 
       throw; 
      } 
     } 
}