1

我知道 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 将如何确保环境事务不会持久化到数据库中?

4

1 回答 1

1

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

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

这在 NHibernate 中似乎仍然相同,并且有两个事务工厂。一种用于分布式事务,一种用于本地事务。但两者都返回AdoTransaction

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

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

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

编辑

另请参阅此问题:TransactionScope 如何回滚事务?

于 2010-02-02T12:53:02.647 回答