過去累積不少MSDTC的茶包處理經驗,也想出了用Mini C# Lab測試MSDTC的技巧。原本射MSDTC茶包還算得心應手,但最近又踢了鐵板,學到新的心得:

  1. SQL 2008啟動分散式交易的時機改變
    依過去的研究心得,只要不是用同一個SqlConnection物件執行查詢,即便連線字串完全相同,SQL 2005也會啟用分散式交易,所以在Mini C# Lab MSDTC測試中,就用了這點特性故意引發分散式交易進行測試。但今天被騙很慘,使用Mini C#測試看來MSDTC正常,但Web程式卻一直傳回分散式交易失敗!
    追了一陣子才赫然發現,原來SQL 2008的LTM容忍度變大了,即便使用不同的SqlConnection,只要連線字串相同,還是適用LTM! 所以我一直用歪尺在量東西,難怪世界是歪的。
    因此,我決定修正Mini C# Lab MSDTC的程式碼,加入
    cnStr += "Application Name=" + Guid.NewGuid().ToString();
    故意造成連線字串永遠不會相同來避開SQL 2008的LTM,並且在結果中顯示Transaction.Current.TransactionInformation.DistributedIdentifier以協助確認有動用到MSDTC!
    using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.Transactions;
    //REFDLL System.Data;System.Xml;System.Transactions
     
    public class CSharpLab
    {
        private static void querySqlServer() 
        {
            string cnStr =  "Data Source=MyServer;User Id=MyUser;Password=MyPwd;";
            cnStr += "Application Name=" + Guid.NewGuid().ToString();
            using (SqlConnection cn = new SqlConnection(cnStr))
            {
                SqlCommand cmd = new SqlCommand("SELECT getdate() as D", cn);
                cn.Open();
                SqlDataReader dr = cmd.ExecuteReader();
                dr.Read();
                Console.WriteLine(dr["D"]);
                cn.Close();
            }
        }
        public static void Test()
        {
            using (TransactionScope tx=new TransactionScope()) 
            {   
                querySqlServer();
                querySqlServer();
                Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier);
                Console.WriteLine(Transaction.Current.TransactionInformation.DistributedIdentifier);
                tx.Complete();
            }
        }
    }

    新的執行結果如下,如果發現最後一組GUID是00000000-0000-0000-0000-000000000000代表分散式交易根本沒有啟動,千萬不要被結果給騙了!! 

    Built successfully in 323ms!
    Prepare to run...
    ==================================================
    11/8/2010 12:57:00 PM
    11/8/2010 12:57:00 PM
    c59168c5-dc86-4ca5-be5e-316af2da7521:32
    00000000-0000-0000-0000-000000000000
    ==================================================
    Execution time: 8 ms

    啟用MSDTC的狀況下,兩組GUID應該都要有值才合理!

    Built successfully in 324ms!
    Prepare to run...
    ==================================================
    11/8/2010 12:59:35 PM
    11/8/2010 12:58:36 PM
    c59168c5-dc86-4ca5-be5e-316af2da7521:33
    df4f40aa-9d43-4b86-b64d-4afbabfd22c3
    ==================================================
    Execution time: 67 ms

  2. Windows 2008 防火牆Issue
    發現MSDTC不通後,又匆忙找原因。最後發現問題出在防火牆設定,預設MSDTC是被關閉的! 啟用後,終於解除了Windows 2008 R2 MSDTC的封印,呼~~~


Comments

# by AA

請問故意引發分散式交易的道理在哪裡? 純粹好奇嗎?

# by Jeffrey

to AA, 引發分散式交易的目的在於驗證該Client與SQL Server間的相關設定妥當,確認該環境能支援分散式交易。

# by SA

請問暗大,當SQL SERVER與IIS SERVER分處不同主機上時下列作業要在哪台設定呢,或是都需要呢 1. 啟用MSDTC (Distributed Transaction Coordinator) 2. 啟用Network DTC Access 3. 啟用DTC對應的防火牆 我是參考下列網址的 (由於本身對技術不熟,若描述有錯誤還請包含) http://www.haodaima.net/art/600045

# by Jeffrey

to SA,依我的理解,執行分散式交易程式的機器及SQL兩台都要設妥MSDTC,我在BizTalk安裝說明上找到相似描述: To enable the adapter to perform operations within the scope of an MSDTC transaction, you must configure MSDTC both on the computer running the SQL adapter and SQL Server. Also, you must add MSDTC to the exceptions list of Windows Firewall. 參考:https://msdn.microsoft.com/en-us/library/dd787924.aspx

# by SA

暗大,感謝您的回覆,我請工程師參考您提供的文章來做對應的設定,大感謝XD

Post a comment