KB-Deadlock Detection And Retrial Sample

最近在處理表單引擎的Deadlock問題,由於引擎核心以物件導向方式開發,很難為了資料庫的更新問題去挪動物件的呼叫順序。但還是努力做了調整,每天Deadlock的發生次數終於壓到個位數,但要100%避免看來是不可能的(至少以我的能力來說是如此)。既然逃不掉,就乖乖面對吧!

一般處理Deadlock的準則是Wait And Retrial,換句話說,程式邏輯本身並沒有任何錯誤,純粹是運氣不好,跟其他Process的資料庫更新作業強碰且被SQL Server挑中變成犠牲品,在絕大部份的情況下,在我們接到Exception的同時,冤家Process也已完成它的作業,釋放Lock。所以只要再試一次,幾乎都會成功。

不過,由於Connection在歷經錯誤後,就無法再參與Tranascation,因此得重新建立Connection再跑。(我自己試的結果,連TransactionScope也要重來才會成功)

測試了好久,總算湊出Workable的演算法如下。其中DataProvider在建立時會開一條Connection,Dispose()時關閉,從頭到尾都用同一條連線做事,如此在TransactionScope可以用效率較佳的LTM機制,不必動用到OleTx(MSDTC)。重試的部分則利用SqlException.Number==-2(Lock timeout)或1205(Deadlock victim)來判定是否需要重試,若是則等待1秒後再試一次。若遇到的不是Lock或Deadlock問題,則沒有理由重試,直接throw Exception。

static void doUpdate()
{
    using (TransactionScope tx = new TransactionScope())
    {
        using (DataProvider dp = new DataProvider())
        {
            //接連新增資料到Emp及Cust兩個Table
            //如果同時有其他Process先新增Cust再新增Emp就會發生Deadlock
            dp.ExecCommand(
                "INSERT INTO Emp VALUES (999, 'Jeffrey', 1)");
            dp.ExecCommand(
                "INSERT INTO Cust VALUES (999, 'Darkthread', 1)");
        }
        tx.Complete();
    }
}
 
static void testDeadlock()
{
    for (int i = 0; i < 3; i++)
    {
        try
        {
            doUpdate();
            break;
        }
        catch (SqlException se)
        {
            if (
                se.Number == -2 //Lock Timeout
                || se.Number == 1205 //Deadlock
                )
            {
                //理論上要寫Log記下這個錯誤
                //這裡用Console.Write意思一下
                Console.WriteLine(se.Message);
                if (i == 2) //第三次不等了,丟Exception
                    throw new
                        ApplicationException("資料庫重試3次失敗!");
                else
                    //前兩次,先等待一小段時間再跑迴圈重試
                    Thread.Sleep(1000);
            }
            else
                throw;
        }
    }
}
歡迎推文分享:
Published 23 August 2007 01:57 PM 由 Jeffrey
Filed under: , , ,
Views: 11,012



意見

沒有意見

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<August 2007>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
2627282930311
2345678
 
RSS
創用 CC 授權條款
【廣告】
twMVC

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication