nhibernate 中缺少对环境事务的支持?

发布于 2024-08-18 07:18:25 字数 833 浏览 5 评论 0原文

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

I know NHibernate supports ambient transactions, because NHibernate sessions enlists in the ambient transactions while inside a transaction scope. However, there are some oddities, consider the following test:

[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); 
    }
}

This test fails. How will NHibernate ensure that the ambient transaction is not persisted to the database?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

往日情怀 2024-08-25 07:18:25

我比较了解 Hibernate 如何在 Java 世界中与 JTA 配合使用,但我不是 .NET 专家。不过你的问题引起了我的注意。

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

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

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

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

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

编辑

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

I know relatively well how Hibernate work with JTA in the Java world, but I am not a .NET expert. Your question nevertheless caught my attention.

In Java, you need to configure Hibernate with either JDBC or JTA transaction. In which case, the Transaction object returned by Hibernate wraps either a transaction that is bound to one database connection (JDBC) or the global transaction that is thread-local. The global thread-local transaction context can be invalidated using UserTransaction#setRollbackOnly, which ensures it will never commit succesfully. It's however preferable to not manage transaction through Hibernate but to use solely the UserTransaction object provided by JTA.

This still seems to be the same in NHibernate and there is two transaction factories. One for distributed transactions and one for local transactions. But both return an AdoTransaction:

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

This doesn't seem to be consistent in case of distributed / ambient transactions. I don't see how rollback would work in this case given that the global transaction context can not be invalided in .NET (so far I understand), and AdoTransaction seems to represent a transaction on database connection.

So I feel like the answer to your question is "it won't" which would explain that your test fails. This means that you should not manage transaction through NHiberate if you use ambient transaction. Just like it's not a recommended practice with Hibernate and JTA.

EDIT

See also this question: How does TransactionScope roll back transactions?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文