2010-01-17 65 views
1

我知道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將如何確保環境事務不會持久化到數據庫?

回答

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似乎代表數據庫連接上的事務。

所以我覺得你的問題的答案是「它不會」,這將解釋你的測試失敗。這意味着如果您使用環境交易,則不應通過NHiberate管理交易。就像這不是Hibernate和JTA推薦的做法。

編輯

另見這個問題:How does TransactionScope roll back transactions?