【茶包射手專欄】錯怪Oracle~~
2 |
本來以為自己堪稱台灣地區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 3、Process 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