【问题标题】:Missing support for ambient transactions in nhibernate?在 nhibernate 中缺少对环境事务的支持?
【发布时间】:2011-11-15 23:08:41
【问题描述】:

我知道 NHibernate 支持环境事务,因为 NHibernate 会话在事务范围内参与环境事务。但是,有一些奇怪的地方,请考虑以下测试:

[Test]
public void Transaction_RollsBackTransactionInsideOfAmbientTransaction_AmbientTransactionAborted()
{
    // arrange
    ISessionFactory sessionFactory = SessionFactoryOneTimeInitializer.GetTestSessionFactory();
    ISession session = sessionFactory.OpenSession();
    SessionFactoryOneTimeInitializer.CreateDataBaseSchemaIfRequiredByConfiguration(session);

    using (new TransactionScope())
    {
        using (ITransaction transaction = session.BeginTransaction())
        {
            // act
            transaction.Rollback();
        }

        // assert
        Assert.AreEqual(TransactionStatus.Aborted, Transaction.Current.TransactionInformation.Status); 
    }
}

此测试失败。 NHibernate 将如何确保环境事务不会持久化到数据库中?

【问题讨论】:

    标签: c# unit-testing nhibernate transactionscope


    【解决方案1】:

    我比较清楚 Hibernate 如何在 Java 世界中与 JTA 一起工作,但我不是 .NET 专家。你的问题还是引起了我的注意。

    在 Java 中,您需要使用 JDBC 或 JTA 事务来配置 Hibernate。在这种情况下,Hibernate 返回的Transaction 对象包装了绑定到一个数据库连接(JDBC)的事务或线程本地的全局事务。可以使用UserTransaction#setRollbackOnly 使全局线程本地事务上下文无效,从而确保它永远不会成功提交。然而,最好不要通过 Hibernate 管理事务,而只使用 JTA 提供的 UserTransaction 对象。

    这在 NHibernate 中似乎仍然相同,并且有两个事务工厂。一种用于distributed transactions,另一种用于local transactions。但两者都返回AdoTransaction

    public ITransaction CreateTransaction(ISessionImplementor session)
    {
        return new AdoTransaction(session);
    }
    

    这在分布式/环境事务的情况下似乎不一致。我看不出rollback 在这种情况下如何工作,因为全局事务上下文在.NET 中不能无效(据我所知),而AdoTransaction 似乎代表数据库连接上的事务。

    所以我觉得你的问题的答案是“它不会”,这可以解释你的测试失败。这意味着如果您使用环境事务,则不应通过 NIBerate 管理事务。就像不推荐使用 Hibernate 和 JTA 一样。

    编辑

    另请参阅此问题:How does TransactionScope roll back transactions?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多