Nhibernate与TransactionScope出现错误 - DTC事务准备阶段失败 -- 升级到Nhibernate 3.0

5

当我在事务范围内使用Nhibernate和ADO.Net操作时,出现了以下异常。例如,使用Nhibernate 2.1时一切正常,但现在升级到3.0会抛出错误。

using (var scope = new TransactionScope(TransactionScopeOption.Required))
{
        GetmemberId(); --> NHibernate Call
        Update(); ADO Call OracleDB
}

由于这是环境事务,Nhibernate试图在外部事务完成之前尽快处理事务。如果我错了,请纠正我,是否有任何解决方案可以帮助我?但是当我将Nhibernate调用移到TransactionScope之外时,一切都正常工作。我给出的示例是一个简单的示例,我的情况涉及更复杂的情况,因为我必须保持两个调用都在TransactionScope内,并且我收到的错误如下:

ERROR 13 NHibernate.Impl.AbstractSessionImpl - DTC transaction prepre phase failed System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Transaction'. at System.Transactions.Transaction.DependentClone(DependentCloneOption cloneOption) at System.Transactions.TransactionScope.SetCurrent(Transaction newCurrent) at System.Transactions.TransactionScope.PushScope() at System.Transactions.TransactionScope.Initialize(Transaction transactionToUse, TimeSpan scopeTimeout, Boolean interopModeSpecified) at System.Transactions.TransactionScope..ctor(Transaction transactionToUse) at NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare(PreparingEnlistment preparingEnlistment) 2011-02-08 13:41:46,033 ERROR 13 NHibernate.Impl.AbstractSessionImpl - DTC transaction prepre phase failed System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Transaction'. at System.Transactions.Transaction.DependentClone(DependentCloneOption cloneOption) at System.Transactions.TransactionScope.SetCurrent(Transaction newCurrent) at System.Transactions.TransactionScope.PushScope() at System.Transactions.TransactionScope.Initialize(Transaction transactionToUse, TimeSpan scopeTimeout, Boolean interopModeSpecified) at System.Transactions.TransactionScope..ctor(Transaction transactionToUse) at NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare(PreparingEnlistment preparingEnlistment)

2个回答

6

尝试使用以下代码:

Configuration.SetProperty(Environment.TransactionStrategy,"NHibernate.Transaction.AdoNetTransactionFactory")

或在nhibernate配置文件中进行设置。

<property name="transaction.factory_class">
NHibernate.Transaction.AdoNetTransactionFactory
</property>

对我来说有效 =)


1
我们遇到了同样的错误,原因是我们在使用NHibernate的Web Api时,会话和事务的使用方式错误。
我们本应该使用session-per-request(每个请求一个会话)。当请求开始时,您应该打开一个会话并启动一个事务。
但我们没有这样做。在我们的存储库中,我们为每个数据库请求创建了一个新的会话和事务。这意味着我们不是为每个请求拥有单个会话/事务,而是有很多个。
对我们而言,错误的根本原因是我们在一个会话中加载实体(领域模型对象),然后在另一个会话中修改并保存它。当NHibernate执行更新调用时,加载会话/事务已经被提交、刷新并关闭了。
解决方案是将我们的会话/事务创建从存储库中提取出来,并移到控制器层(可以使用HttpModule处理REST调用和/或使用依赖注入的面向方面编程)。这个会话/事务将在REST调用或NServiceBus处理程序执行期间存在,并用于该调用期间的所有数据库访问。当该调用结束时,它将被适当地提交或回滚。
上面给出的答案设置config属性只是关闭了DTC并恢复了旧的NHibernate事务处理方式。如果您永远不需要将Web Api扩展到多个实例,则可以解决您的问题,但是如果您需要扩展,则会导致问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接