2010-11-02 104 views
0

我已經設置了NHibernate以便在MS Sql Server 2008的windows服務中運行。我使用常規的TransactionScope來確保操作是原子操作。 NHibernate設置爲每個程序集創建一個會話工廠。多個會話的NHibernate事務問題

我想從3個不同的程序集中編寫對象的更改。 當我使用一個或兩個程序集時,一切正常,但是當我從第三個程序集中添加閱讀時,我遇到了問題。

I.e.讀取/寫入兩個程序集中的對象和寫入對象都可以正常工作,添加程序集中的對象會產生問題。但是,從第三個程序集中讀取而不使用另外兩個程序集中的對象也可以正常工作。我有一種感覺,會議正在爲對方造成問題。

我的代碼是這樣的:

using (var scope = new TransactionScope()) 
{ 
//Read object 1 
//Do changes to object 2 
//Do changes to object 3 
scope.Complete(); 
} 

當我試圖完成我的交易範圍(通過scope.Complete()),我收到以下錯誤信息:

System.Data.SqlClient.SqlException: Microsoft Distributed Transaction Coordinator (MS DTC) has stopped this transaction. 
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) 
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) 
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) 
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) 
at System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction, TdsParserStateObject stateObj, Boolean isDelegateControlRequest) 
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequest transactionRequest, String transactionName, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest) 
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction(TransactionRequest transactionRequest, String name, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest) 
at System.Data.SqlClient.SqlDelegatedTransaction.SinglePhaseCommit(SinglePhaseEnlistment enlistment) 
System.Transactions.TransactionAbortedException: The transaction has aborted. 
at System.Transactions.TransactionStatePromotedAborted.PromotedTransactionOutcome(InternalTransaction tx) 
at System.Transactions.TransactionStatePromotedEnded.EndCommit(InternalTransaction tx) 
at System.Transactions.CommittableTransaction.Commit() 
at System.Transactions.TransactionScope.InternalDispose() 
at System.Transactions.TransactionScope.Dispose() 

有什麼想法?

+0

爲什麼你不使用一個會議工廠的3個組件?有什麼特殊需要? – Pedro 2010-11-02 17:07:39

回答

0

首先檢查你是否正確使用nHibernate和TransactionScope在一起。下面是它應該怎麼做(從Avoiding Leaking Connections With NHibernate And TransactionScope拍攝):

 using (var scope = new TransactionScope(TransactionScopeOption.Required)) 
     { 
      using (var session = sessionFactory.OpenSession()) 
      using (var transaction = session.BeginTransaction()) 
      { 
       // do what you need to do with the session 
       transaction.Commit(); 
      } 
      scope.Complete(); 
     } 

你所得到的錯誤是常見的,如果是「重用」跨越多個事務會話。我發現它是一個痛苦的世界,因爲分佈式事務被提交併在後臺線程上回滾,所以你不知道什麼時候可以重用它們。此外,nHibernate代碼不是線程安全的。因此,我建議從不重用會話,總是按照上面的代碼銷燬它們。

+0

我認爲在NHibernate 2.1的TransactionScope支持開箱(http://stackoverflow.com/questions/646318/nhibernate-with-transactionscope)。 – Unyttig 2010-11-03 08:16:52

+0

它在特定條件下受支持。以上是使用它的最安全的方式。我遇到了回滾問題,導致連接泄漏。當我試圖解決它時,我遇到了其他問題,例如您正在收到的問題。最後,上述工作。 – Iain 2010-11-03 08:38:48

+0

好的。謝謝你的回覆!你知道我在哪裏可以找到有關NHibernate如何與TransactionScopes一起使用的文檔?我已經嘗試過NHForge和'NHibernate'這本書,但都顯得過時了。 – Unyttig 2010-11-04 08:47:00