【问题标题】:Nhibernate with TransactionScope Error - DTC transaction prepre phase failed -- Upgrade to Nhibernate 3.0Nhibernate 与 TransactionScope 错误 - DTC 事务准备阶段失败 - 升级到 Nhibernate 3.0
【发布时间】:2011-06-23 05:51:40
【问题描述】:

在事务 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 尝试在外部事务完成之前尽快处理事务。如果我错了,请纠正我,有什么解决方案可以帮助我,但是当我将 Nhibernate 调用移到 TransactionScope 之外时,一切正常.我给出的示例是示例一,我的示例涉及更复杂的示例,因为我将调用都保留在 TransactionScope 中,并且我得到的错误如下,

错误 13 NHibernate.Impl.AbstractSessionImpl - DTC 事务预处理 阶段失败 System.ObjectDisposedException:无法访问已处置的 目的。对象名称:“交易”。在 System.Transactions.Transaction.DependentClone(DependentCloneOption 克隆选项)在 System.Transactions.TransactionScope.SetCurrent(交易 newCurrent) 在 System.Transactions.TransactionScope.PushScope()
在 System.Transactions.TransactionScope.Initialize(事务 transactionToUse, TimeSpan scopeTimeout, Boolean interopModeSpecified) 在 System.Transactions.TransactionScope..ctor(事务 交易使用)在 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 克隆选项)在 System.Transactions.TransactionScope.SetCurrent(交易 newCurrent) 在 System.Transactions.TransactionScope.PushScope()
在 System.Transactions.TransactionScope.Initialize(事务 transactionToUse, TimeSpan scopeTimeout, Boolean interopModeSpecified) 在 System.Transactions.TransactionScope..ctor(事务 交易使用)在 NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare(PreparingEnlistment 准备入伍)

【问题讨论】:

    标签: nhibernate transactionscope


    【解决方案1】:

    试试

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

    或者在休眠配置中

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

    它对我有用 =)

    【讨论】:

      【解决方案2】:

      我们遇到了同样的错误,这是由我们在 NHibernate 的 Web Api 中使用会话和事务的方式引起的。

      我们应该一直在使用 session-per-request。 (这可以是 Web 请求或 NServiceBus 处理程序的执行。)当请求开始时,您应该打开一个会话并启动一个事务。

      我们没有这样做。在我们的存储库中,我们为每个数据库请求创建了一个新的会话和事务。这意味着我们有很多会话/事务,而不是一个请求的单个会话/事务。

      对我们而言,该错误的根本原因是我们在一个会话中加载实体(域模型对象),对其进行修改,然后使用不同的会话保存它。当 NHibernate 执行更新调用时,加载会话/事务已经被提交、刷新和关闭。

      解决方案是将我们的会话/事务创建从存储库中提取到控制器层(可以使用 HttpModule 进行 REST 调用和/或使用依赖注入进行面向方面的编程)。然后,这个会话/事务在 REST 调用或 NServiceBus 处理程序执行的整个生命周期内都存在,并用于该调用期间的所有数据库访问。当该调用结束时,它将酌情提交或回滚。

      上面给出的设置配置属性的答案只是关闭 DTC 并恢复到旧的 NHibernate 事务处理方式。如果您永远不必将 Web Api 扩展到多个实例,这可能会为您解决问题,但如果您这样做,这会给您带来问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-11
        • 2011-07-08
        • 2012-04-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多