Gav*_*vin 18 sql-server nhibernate session transactions nested
我可以在NHibernate中进行嵌套事务,我该如何实现它们?我正在使用SQL Server 2008,所以支持肯定在DBMS中.
我发现如果我尝试这样的事情:
using (var outerTX = UnitOfWork.Current.BeginTransaction())
{
using (var nestedTX = UnitOfWork.Current.BeginTransaction())
{
... do stuff
nestedTX.Commit();
}
outerTX.Commit();
}
Run Code Online (Sandbox Code Playgroud)
然后到outerTX.Commit()事务处理变为非活动状态时,会在会话AdoTransaction上产生ObjectDisposedException.
因此我们应该创建嵌套的NHibernate会话吗?或者是否有其他类我们应该使用它来包装事务(我听说过TransactionScope,但我不确定那是什么)?
我现在正在使用Ayende的UnitOfWork实现(感谢Sneal).
原谅这个问题的任何天真,我还是NHibernate的新手.
谢谢!
编辑:我发现你可以使用TransactionScope,例如:
using (var transactionScope = new TransactionScope())
{
using (var tx = UnitOfWork.Current.BeginTransaction())
{
... do stuff
tx.Commit();
}
using (var tx = UnitOfWork.Current.BeginTransaction())
{
... do stuff
tx.Commit();
}
transactionScope.Commit();
}
Run Code Online (Sandbox Code Playgroud)
但是我对此并不是很兴奋,因为它锁定了我们使用SQL Server,而且我发现如果数据库是远程的,那么你必须担心启用MSDTC ...还有一个组件要去错误.嵌套事务在SQL中是如此有用和容易,我认为NHibernate可以通过某种方式模拟相同的...
Sat*_*aga 14
NHibernate会话不支持嵌套事务.
以下测试在2.1.2版中始终如此:
var session = sessionFactory.Open();
var tx1 = session.BeginTransaction();
var tx2 = session.BeginTransaction();
Assert.AreEqual(tx1, tx2);
Run Code Online (Sandbox Code Playgroud)
您需要将其包装在一个TransactionScope以支持嵌套事务.
必须启用MSDTC,否则您将收到错误:
{"Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool."}
该实现不支持嵌套,如果您想要嵌套,请使用Ayende 的 UnitOfWork 实现。您使用的实现(至少对于 Web 应用程序)的另一个问题是它在静态变量中保存 ISession 实例。
由于这些原因,我昨天刚刚重写了我们的 UnitOfWork,它最初是基于 Gabriel 的。
我们不使用UnitOfWork.Current.BeginTransaction(),我们使用UnitofWork.TransactionalFlush(),它在最后创建一个单独的事务来立即刷新所有更改。
using (var uow = UnitOfWork.Start())
{
var entity = repository.Get(1);
entity.Name = "Sneal";
uow.TransactionalFlush();
}
Run Code Online (Sandbox Code Playgroud)