我有以下代码在Autofac中为ASP.NET应用程序连接NHibernate ISession:
builder.RegisterAdapter<ISessionFactory, ISession>(factory => factory.OpenSession())
.InstancePerHttpRequest()
.OnActivated(activatedArgs =>
{
var session = activatedArgs.Instance;
session.BeginTransaction();
})
.OnRelease(session =>
{
if (session.Transaction != null && session.Transaction.IsActive)
{
try
{
session.Transaction.Commit();
}
catch(Exception e)
{
session.Transaction.Rollback();
throw;
}
}
});
即使在提交中抛出异常,会话也会正确处理吗?这是与autofac一起正确使用ISession吗?
答案 0 :(得分:2)
否 - 使用Autofac投掷Dispose()
并不是一个好主意。无法保证正确处理其他组件实例。
一般情况下应该避免 - 例如,WCF具有众所周知且长期存在的可用性问题,因为在处置期间连接会丢失。基本的反模式是Dispose()
经常被调用,因为异常正在传播。抛出另一个例外会掩盖原始的
编辑:
作为一个思想实验 - 让我们说在Autofac中使用一些try / catch魔法支持这一点。如果OnRelease()
抛出两个不同的组件会发生什么?我们不能传播这两个例外。此外 - 一旦异常从Autofac中消失,谁能抓住它?现在已经发布了为请求提供服务的所有组件。
希望这有帮助,尼克。
答案 1 :(得分:0)
我不知道Autofac中的NHibernate ISession但是如果你的会话类有一个Dispose()方法,那么你就不会在任何地方调用它。你应该在catch块之后添加一个finally块并将其丢弃。