NHibernate与TransactionScope

时间:2009-03-14 17:33:08

标签: nhibernate transactionscope

有人能给我一个使用TransactionScope和NHibernate的快速概述吗?我是否需要对session / IEnlistmentNotification / etc执行任何特殊操作。让这个工作?有什么陷阱我应该担心吗?例如,我可以替换所有的hibernate事务:

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

用这个?:

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

6 个答案:

答案 0 :(得分:18)

我已经使用nHibernate 2.1一段时间了,经过一些生产问题并尝试了很多变化之后,我们根据Avoiding Leaking Connections With NHibernate And 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提交/回滚发生在后台线程上)。

答案 1 :(得分:7)

我使用不同的供应商测试了它,它只是有效。如果您没有“scope.Complete()”,则事务将回滚。如果有多个持久资源,您可能需要让MSDTC运行所涉及的机器。在这种情况下,MSDTC将自动检测环境ADO.NET事务并管理整个事务。

答案 2 :(得分:6)

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

如果您使用的是SQL Server 7/2000,那么即使您只使用一个数据库/资源​​,您的所有事务也将成为分布式事务。在大多数情况下,这可能不是您想要的,并且性能代价高昂。

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

答案 3 :(得分:4)

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

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

我希望这就是全部; - )

PS:我添加了Oracle详细信息,因为他们关心我和其他人可能会受益。

答案 4 :(得分:1)

此外,如果您使用的是TransactionScope,请升级到NHibernate 2.1。只有2.1才能使NH真正与TransactionScope实现良好的集成。

答案 5 :(得分:1)

Fabio Maulo在与NH-2107相关的评论中表示:

  

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

我会假设明确使用NHibernate的交易没有必要,但显然这是最好的做法