我正在尝试找到在使用NHibernate的Web应用程序中处理事务的最佳解决方案.
我们使用IHttpModule,在HttpApplication.BeginRequest中我们打开一个新会话,然后用ManagedWebSessionContext.Bind(context,session)将它绑定到HttpContext; 我们关闭并取消绑定HttpApplication.EndRequest上的会话.
在我们的Repository基类中,我们总是围绕我们的SaveOrUpdate,Delete,Get方法包装一个事务,例如,根据最佳实践:
public virtual void Save(T entity)
{
var session = DependencyManager.Resolve<ISession>();
using (var transaction = session.BeginTransaction())
{
session.SaveOrUpdate(entity);
transaction.Commit();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果您需要在某个应用程序服务中的某个位置放置一个事务来包含多个存储库调用以保存,删除等,则这不起作用.
所以我们尝试使用TransactionScope(我不想编写自己的事务管理器).为了测试这是否有效,我使用外部TransactionScope,它不会调用.Complete()来强制回滚:
存储库保存():
public virtual void Save(T entity)
{
using (TransactionScope scope = new TransactionScope())
{
var session = DependencyManager.Resolve<ISession>();
session.SaveOrUpdate(entity);
scope.Complete();
}
}
Run Code Online (Sandbox Code Playgroud)
使用存储库的块:
TestEntity testEntity = new TestEntity { Text = "Test1" };
ITestRepository testRepository = DependencyManager.Resolve<ITestRepository>();
testRepository.Save(testEntity);
using (var scope = new TransactionScope())
{
TestEntity entityToChange = testRepository.GetById(testEntity.Id);
entityToChange.Text = "TestChanged"; …Run Code Online (Sandbox Code Playgroud)