34

谁能给我一个快速概述使用 NHibernate 的 TransactionScope?我需要对 session/IEnlistmentNotification/等做任何特别的事情吗?让它工作?有什么我应该担心的陷阱吗?例如,我可以替换我所有的休眠事务:

var transaction = session.BeginTransaction();
try
{
    // code
    transaction.Commit();
}
catch (Exception)
{
    transaction.Rollback();
}

有了这个?:

using (var scope = new TransactionScope())
{
    // code
    scope.Complete();
}
4

6 回答 6

19

我使用 nHibernate 2.1 已经有一段时间了,在经历了一些生产问题并尝试了很多变体之后,我们根据避免与 NHibernate 和 TransactionScope 的泄漏连接确定了以下方法:

        using (var scope = new TransactionScope(TransactionScopeOption.Required))
        {
            using (var session = sessionFactory.OpenSession())
            using (var transaction = session.BeginTransaction())
            {
                // do what you need to do with the session
                transaction.Commit();
            }
            scope.Complete();
        }

由于我们使用的是 MSMQ 和 WCF,所以我们不得不使用环境事务。

我们发现不使用 session.BeginTransaction() 会导致连接泄漏。我们还发现,在提交事务后重新使用会话会导致竞争条件(nHibernate 不是线程安全的,DTSC 提交/回滚发生在后台线程上)。

于 2010-11-03T08:46:26.563 回答
7

我已经使用不同的供应商对此进行了测试,并且可以正常工作。如果您没有“scope.Complete()”,那么事务将回滚。如果有多个持久资源,您可能需要让 MSDTC 运行所涉及的计算机。在这种情况下,MSDTC 将自动检测环境 ADO.NET 事务并管理整个事务。

于 2009-03-30T19:37:36.743 回答
6

如果您使用的连接提供程序支持使用轻量级事务管理器,如 SQL Server 2005/2008,则上述工作正常。

如果您使用的是 SQL Server 7/2000,那么即使您只点击一个数据库/资源​​,您的所有事务都将变为分布式事务。在大多数情况下,这可能不是您想要的,并且在性能方面会很昂贵。

因此,请检查您的连接提供程序和数据库服务器组合是否适合与 TransactionScope 一起使用。

于 2009-07-06T09:55:07.310 回答
6

我相信你可以用这个替换 NHibernate 事务,只要你尊重一些约束,正如一些人已经说过的:

  • 使用相当新的 NHibernate 版本(>=3.1)。
  • 底层 ADO.NET 数据提供程序必须支持 TransactionScope(适用于 SQL-Server,Oracle >= 10 和 ODP.NET)。
  • TransactionScope 中创建您的 NH 会话以确保它被登记。
  • 手动处理 NHibernate冲洗。另请参阅此处此处
  • 准备分布式事务。如果您在一个范围内创建多个会话,最初的本地事务可能会升级为分布式事务。即使在使用 ODAC 11.2.0.3.20 的 Oracle 11.2 DB 上使用相同的连接字符串,我也看到了这种情况。在 SQL-Server 2008 R2 上它没有提升。(顺便说一句,可以通过观看 Transaction.Current.TransactionInformation.DistributedIdentifier 来了解这一点,这对于本地事务来说是空的。)虽然分布式事务有一些优点,但它们更昂贵,而且设置它们会带来一些额外的痛苦。(请参阅此处如何为 Oracle 执行此操作)。为确保 Oracle 中永远不会发生升级,请在连接字符串中设置“ Promotable Transaction =local”。如果某些代码尝试这样做,则会产生异常。

我希望这就是全部;-)

PS:我添加了 Oracle 详细信息,因为它们是我和其他人可能受益的地方。

于 2013-02-28T13:06:33.700 回答
1

根据 Fabio Maulo 在与NH-2107相关的评论中所说:

你可以使用 TransactionScope,你也应该继续使用 NH 的事务。您在哪里读到 TransactionScope 的使用意味着避免使用 NH 的事务?

我会假设没有必要明确使用 NHibernate 的事务,但显然这是最佳实践

于 2010-09-14T12:46:35.133 回答
1

此外,如果您使用 TransactionScope,请升级到 NHibernate 2.1。只有在 2.1 中,NH 才真正与 TransactionScope 很好地集成。

于 2009-11-16T20:14:34.733 回答