2009-11-18 43 views
6

我剛開始使用TransactionScope,我發現總會有意想不到的事情發生,需要永遠調試。使用TransactionScope和MS DTC時的常見問題

我認爲擁有這些統一的列表對於那些「奇怪的錯誤」情況非常有用,另外還可以擴展我們對平臺怪異性的瞭解。

關於我如何去使用事務範圍的一些背景:

  • Web應用程序
  • 多個Web服務器,應用服務器和SQL服務器
  • 交易將主要是數據庫事務,但有的會提升寫入MSMQ。

回答

3

兩件事情從我的頭頂:

    當你在同一範圍內使用超過一個連接對象,即使連接具有相同的ConnectionString
  • 交易將提高(這是固定的在SQL 2008)。詳情請閱讀this threaddbconnectionscope將解決在SQL這個問題2005年
  • MSDTC實例需要能夠看到對方,需要有自己的安全設置正確 http://support.microsoft.com/kb/899191(允許入站和出站,不要求相互認證通常是最安全的賭注)。使用DTCPing解決DTC實例之間的連接問題如下解釋:http://support.microsoft.com/kb/306843

你想交易是輕量級儘可能,DTC引入了大量的開銷。您還希望事務越短越好,因此只能在應用程序服務器上引入它們,而不要在Web服務器上引入它們。通過儘可能小且儘可能快的應用服務器和數據庫之間的網絡跳過網絡和應用服務器之間的網絡流量,而不是通過應用服務器和數據庫之間的不同連接發送網絡流量,並使最後一個網絡流量快速尖叫,可笑的短連接。

如果您有多個應用程序服務器,可以考慮在服務器上運行一個單一的msdtc實例(例如,在數據庫或應用程序服務器上),並從所有應用程序服務器遠程使用它,而不是每個運行他們自己,但我不知道這有什麼額外的好處。

+1

它確實在SQL Server 2008中修復了嗎?我正在使用SQLS2008,並且當我使用相同的連接字符串打開第二個連接時,事務將獲得分佈式GUID。那麼......就是在客戶端,還是真的變成了分佈式事務? – Triynko 2010-05-22 18:04:05

+0

請參閱http://msdn.microsoft.com/en-us/library/ms172070%28VS.90%29.aspx 我還沒有爲自己測試過,但根據文檔,應該至少有一個似是而非的方案SQL 2008的行爲如此。也許調整你的連接字符串來明確控制池可能會有所幫助。 – stombeur 2010-05-25 13:19:54

+1

看起來像SQL Server 2008無法解決,看到事務提升到DTC,並且連接字符串和本地數據庫相同 – mamu 2010-07-15 13:43:06

-2

如果使用SQL Server和檢查@@ TRANCOUNT,這將是0,即使你有一個活躍的TransactionScope。

+1

它不會爲零;我只是測試它。您可能會在事務處理範圍之前打開連接,這意味着您的連接根本沒有參與事務(我剛學過的東西,請參閱我的帖子:http://stackoverflow.com/questions/2884863/under-what -circumstances-是-AN-的SqlConnection-自動-徵功能於一個-環境/ 2886326#2886326)。在事務範圍內打開連接,或者通過調用connection.EnlistTransaction(Transaction.Current)顯式地在範圍內徵用現有事務。運行「select @@ trancount」來查看它的非零值。 – Triynko 2010-05-22 18:28:54

1

還要注意的是,如果你在交易過程中更改任何對象,他們不會,除非你添加代碼來處理這個回滾。

TransactionScope and rolling back object state

+0

什麼?如果你正在談論數據庫對象,那不是事實。如果您在事務範圍中登記的連接上發出命令,而您沒有提交該命令,則在處置範圍時,變更將回滾,就像任何其他事務一樣。如果你在談論非數據庫對象,比如文件和應用程序變量,那麼是的......因爲它們與事務無關。 – Triynko 2010-05-22 18:34:20

+0

當我使用'TransactionScope'和DDL時,我有很奇怪的行爲 - 我不得不擺脫'TransactionScope'並使用普通的顯式事務來修復它。 – Lucero 2010-12-07 08:40:19

0

希望這會幫助別人第一天:

如果你有一個內部的多個SQL操作一個TransactionScope時,DTC不會涉及提供

  1. 您使用相同的每個連接的連接字符串
  2. 連接不是嵌套的。

I.e.打開,做某事,關閉。打開,做些事情,關閉。

現在的疑難雜症: 如果你這樣做你的進程(在另一個線程)

SqlConnection.ClearAllPools()

,併發生這種情況你的兩個操作之間來 - 的DTC將立即介入。如果您沒有運行DTC,它會拋出異常。