在嵌套的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语句中进行回滚吗?你能帮我提供正确的方法吗?
答案 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;
}
}
}