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

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

我比较熟悉Hibernate如何在Java世界中使用JTA,但我不是.NET专家。 然而你的问题引起了我的注意。

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

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

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

在分布式/环境事务的情况下,这似乎不一致。 我没有看到rollback在这种情况下如何工作,因为全局事务上下文不能在.NET中无效(到目前为止我理解),并且AdoTransaction似乎代表数据库连接上的事务。

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

编辑

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