2012-11-15 39 views
1

失敗當試圖調試的東西,我發現代碼被有效執行以下操作:的TransactionScope與未提交的第一個事務上的分佈式事務

  1. 創建一個TransactionScope
  2. 創建交易(在這種情況下,NHibernate的TX,但並不重要)
  3. 創建第二個交易(在這種情況下,一個標準的ADO.Net的Tx)
  4. 在提交第二交易
  5. 調用有限公司交易範圍上的完整()
  6. 處置交易範圍。

現在 - 創建一個事務而不是提交可能是一個壞主意 - 尤其是當有(這是錯誤修復)。

但是,當測試這個 - 我嘗試了上述各種組合(提交所有事務,一些事務,沒有事務(即只有TScope)提交第一個,但不是第二個,添加其他事務等),並在所有我找到下列是真實的:

只有當我無法提交第一次交易和交易範圍變得分佈時,TScope的Dispose會失敗:

System.InvalidOperationException:操作是無效的入伍的當前狀態。

我現在很好奇,想知道爲什麼會出現這種情況?

+1

我很困惑。 TransactionScope的目的是擁有一個單一的事務,無論是本地/輕量級還是分佈式事務。 TransactionScope中的多個事務不是它設計要做的事情,它違背了它的目的,即基本上讓事務在TransactionScope的後臺處理。你是指多重連接? – Maarten

+0

好的..所以..進一步點以上兩點。 以上看起來並不真實 - 任何創建的nHibernate事務在TScope中都未打開會導致問題。 澄清混淆: 我們目前有一個沒有事務範圍的nHibernate堆棧。我們現在需要連接到另一個數據庫。所有的例子我看到好像有: 1.打開TS 2.打開NH的Tx 3. perorm NH工作 4提交NH的Tx 5做其他DB WRK 6完整/ TS處置 你saing,如果我們使用TransacionScope,我們根本不應該使用nH事務? 另外 - 我們需要在NH trans內做其他數據庫工作。 – kenam

+0

順便說一句 - TScope似乎是我們想要的原因,因爲我們並不總是需要做「其他數據庫工作」 - 因此TScope會將它踢入分佈式事務中。也許只使用TScope(並且沒有NH Transaction)是正確的解決方案 - 因爲它會創建一個Transaction? – kenam

回答

1

我懷疑你看到的問題是由其中的一個覆蓋:https://nhibernate.jira.com/issues/?jql=project%20%3D%2010000%20AND%20labels%20%3D%20TransactionScope

我不能完全肯定發生了什麼,但我見過類似的行爲,例如如果NH登記環境交易,並且事務後來變得分佈式,則調用TransactionScope.Complete()可能會掛起20秒,然後失敗。

即使您不使用NH事務,NH也會嘗試登記TransactionScope。在這種情況下,NH將在環境事務的Prepare()階段刷新更改。它將在數據庫連接上執行此操作,但該操作也已在事務中使用,並將獲得自己的Prepare()調用。不幸的是,我一直無法弄清楚確切的問題,但我懷疑會發生什麼,在某些情況下,db連接Prepare()將在NHibernate的Prepare()之前調用。後者將嘗試繼續使用數據庫連接,並且看起來會導致某種死鎖。

使用NH事務並在完成事務作用域之前提交它將使NH在其底層數據庫連接進入準備階段之前清空其更改。

+0

它絕對是相似的 - 只有當tx變成分佈式時。我會確保我總是有一個nH交易。更多問題: 1.將ADO.Net工作嵌套在NH Begin/commit Transaction中會有問題嗎? 2.應該在提交後處理nH事務嗎?我注意到(目前在添加TScope之前)我們嘗試提交事務,然後將其處置並開始新的nH事務。 – kenam

+0

如果ADO.Net工作用於不同的數據庫,則它將使用單獨的容器。 NH不關心重疊的壽命。如果工作與NH連接的同一個DB,則應使用NH已經管理的連接(和事務)。 2)一次性物品應該一直處置。 –