在嵌套的NHibernate语句中捕获异常

时间:2017-02-06 09:49:40

标签: c# nhibernate exception-handling

在嵌套的using语句中处理异常的正确方法是什么?我有以下部分代码:

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语句时,我看到了很少的答案。我知道using语句包含try / finally。我的问题是关于捕捉所有可能的例外的正确方法。我应该在catch语句中进行回滚吗?你能帮我提供正确的方法吗?

2 个答案:

答案 0 :(得分:2)

我倾向于最小化"尝试捕获"条款尽可能多。

嵌套"尝试捕获"并记录每个catch(虽然不吞咽异常)可能会导致多次记录同一个异常,这会使日志膨胀。并且"尝试赶上"处处充斥着代码。

我认为没有必要显式回滚失败的事务:默认情况下,在已处置的情况下回滚非已提交的事务。

我使用MVC / webform的常用模式是使用全局操作过滤器(通常派生自HandleErrorAttribute)来记录异常,和/或专用的IHttpModule。因此,不需要尝试捕捉"其他任何地方只是为了记录,而不是吞下异常。

(对于MVC,我通常会显式回滚失败的事务,因为我使用操作过滤器打开它们OnActionExecuting,根据OnActionExecuted状态提交或回滚它们filterContext。如果有错误,我可以添加一个吞咽和记录的尝试捕获回滚:它也可能失败,我认为这个失败不应该掩盖导致应用程序尝试回滚的那个。)

答案 1 :(得分:0)

我遵循BeginTransaction()之后立即开始try..catch块的模式。

除此之外,我认为不添加任何其他异常检查是正常的 - 只需让它传播到调用代码。

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