在事务Scope.Eg中使用Nhibernate和ADO.Net操作时,我收到以下异常。 Nhibernate 2.1很好,但现在升级到3.0,这会引发错误。
using (var scope = new TransactionScope(TransactionScopeOption.Required))
{
GetmemberId(); --> NHibernate Call
Update(); ADO Call OracleDB
}
由于这充当了环境事务,Nhibernate试图在外部事务完成之前很快处理事务。如果我错了,请修正我,是否有任何解决方案因为帮助我,但是当我在TransactionScope外部移动Nhibernate调用时一切正常。我给出的示例是示例一,mines涉及更复杂的一个,因为我在TransactionScope中保留了两个调用,并且Iam得到的错误如下,
错误13 NHibernate.Impl.AbstractSessionImpl - DTC事务预处理 阶段失败System.ObjectDisposedException:无法访问已处置的 宾语。对象名称:'交易'。在 System.Transactions.Transaction.DependentClone(DependentCloneOption cloneOption) System.Transactions.TransactionScope.SetCurrent(交易 System.Transactions.TransactionScope.PushScope()的newCurrent 在System.Transactions.TransactionScope.Initialize(Transaction transactionToUse,TimeSpan scopeTimeout,Boolean interopModeSpecified) 在System.Transactions.TransactionScope..ctor(交易 transactionToUse)at NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare(PreparingEnlistment 准备入境)2011-02-08 13:41:46,033错误13 NHibernate.Impl.AbstractSessionImpl - DTC事务预处理阶段 System.ObjectDisposedException失败:无法访问已释放的 宾语。对象名称:'交易'。在 System.Transactions.Transaction.DependentClone(DependentCloneOption cloneOption) System.Transactions.TransactionScope.SetCurrent(交易 System.Transactions.TransactionScope.PushScope()的newCurrent 在System.Transactions.TransactionScope.Initialize(Transaction transactionToUse,TimeSpan scopeTimeout,Boolean interopModeSpecified) 在System.Transactions.TransactionScope..ctor(交易 transactionToUse)at NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare(PreparingEnlistment preparingEnlistment)
答案 0 :(得分:6)
尝试
Configuration.SetProperty(Environment.TransactionStrategy,"NHibernate.Transaction.AdoNetTransactionFactory")
或者在nhibernate配置
<property name="transaction.factory_class">
NHibernate.Transaction.AdoNetTransactionFactory
</property>
它对我有用=)
答案 1 :(得分:1)
我们遇到了同样的错误,这是由我们使用NHibernate在Web Api中使用会话和事务的方式引起的。
我们应该一直在使用session-per-request。 (这可以是Web请求或执行NServiceBus处理程序。)当请求启动时,您应该打开一个会话并启动一个事务。
我们没有这样做。在我们的存储库中,我们为每个数据库请求创建了一个新的会话和事务。这意味着我们有很多,而不是为请求提供单个会话/事务。
我们的错误的根本原因是我们在一个会话中加载一个实体(域模型对象),修改它,并使用不同的会话保存它。当NHibernate执行更新调用时,加载会话/事务已经被提交,刷新和关闭。
解决方案是将我们的会话/事务创建从存储库中拉出到Controller层(可以使用HttpModule进行REST调用和/或使用依赖注入进行面向方面编程)。然后,这一个会话/事务将在REST调用或NServiceBus处理程序执行的生命周期中存在,并在该调用期间用于所有数据库访问。当该呼叫结束时,它将在适当时提交或回滚。
上面给出的答案设置配置属性只是关闭DTC并恢复到旧的NHibernate事务处理方式。如果您不必将Web Api扩展到多个实例,这可能会为您解决问题,但如果您这样做,这将导致您出现问题。