【发布时间】:2011-03-11 15:49:13
【问题描述】:
我通过一组接口在我的应用程序中使用 NHibernate。 ISession 封装在一个名为 IUnitOfWork 的接口中,其具体实现如下所示:
public class UnitOfWork : IUnitOfWork
{
private ISession _session;
public UnitOfWork()
{
_session = KctcSessionFactory.OpenSession();
}
public void Dispose()
{
try
{
_session.BeginTransaction();
_session.Flush();
_session.Transaction.Commit();
}
catch (Exception)
{
_session.Transaction.Rollback();
_session.Transaction.Dispose();
throw;
}
}
public T Load<T>(int id)
{
return _session.Load<T>(id);
}
public IQueryable<T> GetList<T>()
{
return _session.Linq<T>();
}
public void Save(object entity)
{
_session.SaveOrUpdate(entity);
}
public void Delete(object entity)
{
_session.Delete(entity);
}
}
IUnitOfWork 由温莎城堡经营,生活方式为PerWebRequest。这意味着从 Web 请求的角度来看,IUnitOfWork 实际上是一个单例,并在请求结束时自动释放。
这段代码在我看来完全是万无一失的。当IUnitOfWork 在 Web 请求结束时被释放时,所有保存的实体都将被刷新,并且整个操作被包装在一个事务中,因此它是原子完成的。我不应该在这个类之外使用事务。我对吗?这段代码安全吗?还是我错过了什么可怕的事情?
为清楚起见进行了编辑:我想知道我是否正确假设所有刷新/提交到数据库将等到会话被释放,因此可以包装在单个事务中Dispose 方法。或者是否存在在我在 Dispose 方法中明确执行数据之前可能会刷新数据的情况?或者我可能出于其他原因需要显式使用事务?
【问题讨论】:
-
哎呀!我刚刚意识到当我可以提交事务时我不需要 _session.Flush() 。顺便说一句,这不是生产代码。
标签: nhibernate transactions castle-windsor unit-of-work