本來以為自己堪稱台灣地區Trouble-Shoot MSDTC問題的權威,沒想到這幾天陰溝裡翻船,為了解決一台新灌XP SP2無法啟用分散式交易的問題,耗掉近一個人天...

同事回報,照著我先前的KB設定了分散式交易,但是執行以下的Code,程式卻會卡在第11開啟Oracle Connection上,卡住約三分鐘,然後丟出Communication with the underlying transaction manager has failed.之類的Error。

   1:  private static void oraDtc() 
   2:  {
   3:      using (TransactionScope tx = new TransactionScope())
   4:      {
   5:          string sqlCnStr = "Data Source=theSQL2005;User Id=blah;Password=blah";
   6:          SqlConnection cnS = new SqlConnection(sqlCnStr);
   7:          cnS.Open();
   8:          cnS.Close();
   9:          string oraCnStr = "Data Source=theOracle;User Id=blah;Password=blah";
  10:          System.Data.OracleClient.OracleConnection cnO =
 new OracleConnection(oraCnStr);
  11:          cnO.Open();
  12:          cnO.Close();
  13:      }
  14:  }

一時鬼迷心竅(當然,也有可能農曆七月的關係),看程式停在Oracle的連線開啟上,就認定問題出在Oracle上,忘了System.Transactions具有LTM->OleTx的精巧特性(後面會再介紹),死命地查Oracle Service for MTS、Oracle Client版本,甚至還重裝了一次Oracle Client,動用了Net Monitor 3Process Monitor等重量級工具,還學會了設定ORAMTS_CP_TRACE_LEVEL Registry追蹤ORAMTS Log的技巧(真是意外的收獲)。不過,各式重量級武器精鈍盡出,我卻只得到一個結論: Oracle連線沒出現任何錯誤,程式Hang住的那三分鐘,nothing happened, of course, nothing wrong。我另外做了一個實驗,在ASP裡透過宣告<%@ Transaction=Required%>包了一個OLE DB的Oracle Connection,卻可以達陣成功(MSDTC的Commit數加1)... 這...

一陣膠著之後,忽然福至心靈,到目前為止一直以Oracle為焦點,並沒有親眼見證SQL的分散式交易成功,該不會問題出在SQL的分散式交易上??

這就對了,關鍵在於LTM(Light Weight Transaction Manager)! 當.NET 2.0發現整個TransactionScope中只涉及一台SQL Server 2005時,可以不啟用OleTx,不驚動MSDTC,直接使用LTM更有效率地完成交易。而最方便的一點是,.NET 2.0會依參與交易的對象、數目決定使用LTM或是OleTx,對開發人員完全透明。所以我遇到的情況應該是在開啟Oracle Connection時,.NET 2.0發現已達啟用分散式交易的條件,原本的SQL連線須由LTM改為OleTx,若SQL連線升級失敗,或許就是導致分散式交易失敗的原因。

這解釋了為什麼Oracle Connection在開啟時Hang住,沒有動作好一陣子後傳回Transaction錯誤的現象。Oracle Connection的出現導致先前的SQL Connection要升級為分散式交易,苦等不到SQL Connection註冊MSDTC成功,Oracle Connection只有含淚背上了"導致交易失敗"的黑鍋。

再做兩個測試,TransactionScope包兩條SQL Connection失敗,包兩條Oracle Connection成功,Bingo!! 問題根源一旦明確,解決過程就變成一塊蛋糕(Piece of Cake)。依照先前TIPS-TransactionScope過三關的技巧,很快地問題就排除了,Case Closed!

PS: 9月的RUN!PC會有一篇我的文章,介紹搞分散式交易的一些實務技巧(血淚辛酸? XD),還用實驗驗證與觀察TransactionScope的特性(包含上述LTM->OleTx的過程),有興趣的人可以去書店翻翻。


Comments

# by eriyu

您好,我最近在使用TransactionScope時,也遇到Oracle Connection 無法開啟 ,利用TransactionInformation去查看,發現是因為SQL連線仍然是LTM而非OleTx,所以造成交易無法正常作用發生例外,然後我用TransactionScope包OracleConnection一直會有問題,但包SqlConnection就沒有問題,一直找不到出問題的原因>,< 可以請您指點我TroubleShooting的方向嗎? 謝謝

# by Jeffrey

to eriyu, 你提供的資訊不太多,不太看得出問題何在,我原。文中所說的RUN!PC文章".NET分散式交易程式開發FAQ"我已放在網站上,不知你是否有看過,希望可以給你一些靈感。http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/05/09/distributed-transactoin-with-dotnet-faq.aspx

Post a comment